//
// Copyright (c) 2017 The Khronos Group Inc.
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef _TESTNONUNIFORMWORKGROUP_H
#define _TESTNONUNIFORMWORKGROUP_H

#include "procs.h"
#include <vector>
#include "tools.h"
#include <algorithm>

#define MAX_SIZE_OF_ALLOCATED_MEMORY (400*1024*1024)

#define NUMBER_OF_REGIONS 8

#define MAX_DIMS 3

// This structure reflects data received from kernel.
typedef struct _DataContainerAttrib
{
  cl_ulong get_global_size[MAX_DIMS];
  cl_ulong get_global_offset[MAX_DIMS];
  cl_ulong get_local_size[MAX_DIMS];
  cl_ulong get_enqueued_local_size[MAX_DIMS];
  cl_ulong get_global_id[MAX_DIMS];
  cl_ulong get_local_id[MAX_DIMS];
  cl_ulong get_group_id[MAX_DIMS];
  cl_ulong get_num_groups[MAX_DIMS];
  cl_ulong get_work_dim;
  cl_ushort test_local_barrier_result_bool;
  cl_ushort test_global_barrier_result_bool;
  cl_ushort test_local_atomic_result_value;
}DataContainerAttrib;

// Describes range of testing.
namespace Range {
  enum RangeEnum {
    BASIC = (1 << 0),
    BARRIERS = (1 << 1),
    ATOMICS = (1 << 2),

    ALL = Range::BASIC | Range::BARRIERS | Range::ATOMICS
  };
}

std::string showArray (const size_t *arr, cl_uint dims);

// Main class responsible for testing
class TestNonUniformWorkGroup {
public:
    TestNonUniformWorkGroup(const cl_device_id &device,
                            const cl_context &context,
                            const cl_command_queue &queue, const cl_uint dims,
                            size_t *globalSize, const size_t *localSize,
                            const size_t *buffersSize,
                            const size_t *globalWorkOffset,
                            const size_t *reqdWorkGroupSize = NULL);

    ~TestNonUniformWorkGroup();

    static size_t getMaxLocalWorkgroupSize(const cl_device_id &device);
    static void setMaxLocalWorkgroupSize(size_t workGroupSize)
    {
        TestNonUniformWorkGroup::_maxLocalWorkgroupSize = workGroupSize;
    }
  static void enableStrictMode (bool state);

  void setTestRange (int range) {_testRange = range;}
  int prepareDevice ();
  int verifyResults ();
  int runKernel ();

private:
  size_t _globalSize[MAX_DIMS];
  size_t _localSize[MAX_DIMS];
  size_t _globalWorkOffset[MAX_DIMS];
  bool _globalWorkOffset_IsNull;
  size_t _enqueuedLocalSize[MAX_DIMS];
  bool _localSize_IsNull;
  size_t _reqdWorkGroupSize[MAX_DIMS];
  static size_t _maxLocalWorkgroupSize;
  size_t _maxWorkItemSizes[MAX_DIMS];
  size_t _numOfGlobalWorkItems; // in global work group
  const cl_device_id _device;
  const cl_context _context;
  const cl_command_queue _queue;
  const cl_uint _dims;

  int _testRange;

  std::vector<DataContainerAttrib> _resultsRegionArray;
  std::vector<DataContainerAttrib> _referenceRegionArray;
  cl_uint _globalAtomicTestValue;

  clProgramWrapper _program;
  clKernelWrapper _testKernel;

  Error::ErrorClass _err;

  TestNonUniformWorkGroup ();

  static bool _strictMode;
  void setLocalWorkgroupSize (const size_t *globalSize, const size_t *localSize);
  void setGlobalWorkgroupSize (const size_t *globalSize);
  void verifyData (DataContainerAttrib * reference, DataContainerAttrib * results, short regionNumber);
  void calculateExpectedValues ();
  void showTestInfo ();
  size_t adjustLocalArraySize(size_t localArraySize);
  size_t adjustGlobalBufferSize(size_t globalBufferSize);
};

// Class responsible for running subtest scenarios in test function
class SubTestExecutor {
public:
  SubTestExecutor(const cl_device_id &device, const cl_context &context, const cl_command_queue &queue)
    : _device (device), _context (context), _queue (queue), _failCounter (0), _overallCounter (0) {}

  void runTestNonUniformWorkGroup(const cl_uint dims, size_t *globalSize,
                                  const size_t *localSize, int range);

  void runTestNonUniformWorkGroup(const cl_uint dims, size_t *globalSize,
                                  const size_t *localSize,
                                  const size_t *globalWorkOffset,
                                  const size_t *reqdWorkGroupSize, int range);

  int calculateWorkGroupSize(size_t &maxWgSize, int testRange);
  int status();

private:
  SubTestExecutor();
  const cl_device_id _device;
  const cl_context _context;
  const cl_command_queue _queue;
  unsigned int _failCounter;
  unsigned int _overallCounter;
};

#endif // _TESTNONUNIFORMWORKGROUP_H

