//
// 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 test_conformance_check_mem_host_write_only__h
#define test_conformance_check_mem_host_write_only__h

#include "checker.h"

template < class T> class cBuffer_check_mem_host_write_only : public cBuffer_checker<T>
{
public:
  cBuffer_check_mem_host_write_only(cl_device_id deviceID, cl_context context, cl_command_queue queue)
  : cBuffer_checker < T > (deviceID, context, queue)
  {
    this->m_nNumber_elements = 1000;
  };

  ~cBuffer_check_mem_host_write_only()
  {
  };

  cl_program program;
  cl_kernel kernel;

  clMemWrapper m_buffer2;

  cl_int Setup_Test_Environment();

  cl_int SetupBuffer();
  cl_int SetupASSubBuffer(cl_mem_flags flag_p);

  cl_int verifyData(cl_int err, cl_event &event );
  cl_int update_host_mem_2();

  cl_int verify_RW_Buffer();
  cl_int verify_RW_Buffer_rect();
  cl_int verify_RW_Buffer_mapping();

  C_host_memory_block<T> tmp_host_m;

  virtual cl_int verify_Buffer_initialization();
};

template < class T >
cl_int cBuffer_check_mem_host_write_only< T >::SetupBuffer()
{
  T vv1 = 0;
  this->host_m_1.Init( this->m_nNumber_elements, vv1); // zero out buffer

  // init buffer to 0
  cl_int err;
  int block_size_in_byte = this->get_block_size_bytes();

  this->m_buffer = clCreateBuffer(this->m_context, this->buffer_mem_flag,
                                  block_size_in_byte, this->host_m_1.pData, &err);
  test_error(err, "clCreateBuffer error");

  err = this->Check_GetMemObjectInfo(this->buffer_mem_flag);

  if (this->buffer_mem_flag | CL_MEM_USE_HOST_PTR)
  {
    this->pHost_ptr = (void *)this->host_m_1.pData;
  }

  return err;
}

template < class T >
cl_int cBuffer_check_mem_host_write_only<T>::SetupASSubBuffer(cl_mem_flags flag_p)
{
  return cBuffer_checker<T>::SetupASSubBuffer(flag_p);
}

template < class T >
cl_int cBuffer_check_mem_host_write_only< T >::Setup_Test_Environment()
{
  cl_int err;
  T vv2 = 0;
  this->host_m_2.Init(this->m_nNumber_elements, vv2);

  // init buffer2 to 0
  cl_mem_flags buffer_mem_flag2 = CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR | CL_MEM_HOST_READ_ONLY;
  this->m_buffer2 = clCreateBuffer(this->m_context, buffer_mem_flag2,
                                   this->get_block_size_bytes(), this->host_m_2.pData, &err);
  test_error(err, "clCreateBuffer error\n");

  return err;
}

template < class T >
cl_int cBuffer_check_mem_host_write_only< T >::verify_Buffer_initialization()
{
  cl_int err = CL_SUCCESS;

  if (this->host_m_1.pData == NULL || this->host_m_2.pData == NULL) {
    log_error("Data not ready\n");
    return FAILURE;
  }

  update_host_mem_2();

  if (!this->host_m_1.Equal(this->host_m_2)){
    log_error("Buffer content difference found\n");
    return FAILURE;
  }

  return err;
}

template < class T >
cl_int cBuffer_check_mem_host_write_only< T >::verify_RW_Buffer()
{
  T vv1 = TEST_VALUE;
  T vv2 = 0;
  this->host_m_2.Set_to(vv2);

  tmp_host_m.Init(this->host_m_1.num_elements, vv1) ;

  cl_event event;
  cl_int err = CL_SUCCESS;
  err = clEnqueueWriteBuffer(this->m_queue, this->m_buffer, this->m_blocking, 0,
                             this->get_block_size_bytes(), tmp_host_m.pData,
                             0, NULL, &event);
  if (err != CL_SUCCESS ) {
    test_error(err, "clEnqueueWriteBuffer error");
  }

  if (!this->m_blocking){
    err = clWaitForEvents(1, &event);
    test_error(err, "clWaitForEvents error")
  }

  err = clReleaseEvent(event);
  test_error(err, "clReleaseEvent error");

  if (tmp_host_m.Equal(this->host_m_2)){
    log_error("Test data should be different\n");
    return FAILURE;
  }

  update_host_mem_2();

  if (!tmp_host_m.Equal(this->host_m_2)){
    log_error("Buffer content difference found\n");
    return FAILURE;
  }

  err = clEnqueueReadBuffer(this->m_queue, this->m_buffer, CL_TRUE, 0,
                            this->get_block_size_bytes(), this->host_m_2.pData,
                            0, NULL, &event);

  if ( err == CL_SUCCESS ) {
    log_error("Calling clEnqueueReadBuffer on a memory object created with the CL_MEM_HOST_WRITE_ONLY flag should not return CL_SUCCESS\n");
    err = FAILURE;
    return FAILURE;

  } else {
    log_info("Test succeeded\n\n");
    err = CL_SUCCESS;
  }

  return  err;
}

template < class T >
cl_int cBuffer_check_mem_host_write_only< T >::verify_RW_Buffer_rect()
{
  this->Init_rect();

  T vv1= TEST_VALUE;
  this->host_m_1.Set_to(vv1);

  T vv2 = 0;
  this->host_m_2.Set_to(vv2);

  cl_event event, event_1;

  cl_int err = CL_SUCCESS;

  vv1 = 0;
  C_host_memory_block< T > tmp_host_m;
  tmp_host_m.Init(this->host_m_1.num_elements, vv1); // zero out the buffer
  err = clEnqueueWriteBuffer(this->m_queue, this->m_buffer, CL_TRUE, 0,
                             this->get_block_size_bytes(), tmp_host_m.pData,
                             0, NULL, &event_1);
  test_error(err, "clEnqueueWriteBuffer error");

  vv1 = TEST_VALUE;
  tmp_host_m.Set_to(vv1);
  err = clEnqueueWriteBufferRect(this->m_queue, this->m_buffer, this->m_blocking,
                                 this->buffer_origin_bytes,
                                 this->host_origin_bytes,
                                 this->region_bytes,
                                 this->buffer_row_pitch_bytes,
                                 this->buffer_slice_pitch_bytes,
                                 this->host_row_pitch_bytes,
                                 this->host_slice_pitch_bytes,
                                 tmp_host_m.pData,
                                 1, &event_1, &event);
  test_error(err, "clEnqueueWriteBufferRect error");

  if (!this->m_blocking) {
    err = clWaitForEvents(1, &event);
    test_error(err, "clWaitForEvents error")
  }

  if (tmp_host_m.Equal(this->host_m_2)) {
    log_error("Test data should be different\n");
    return FAILURE;
  }

  err = clReleaseEvent(event_1);
  test_error(err, "clReleaseEvent error");
  err = clReleaseEvent(event);
  test_error(err, "clReleaseEvent error");

  update_host_mem_2();

  size_t tot_in_reg = this->region[0] * this->region[1] * this->region[2];
  if (!tmp_host_m.Equal_rect(this->host_m_2, this->host_origin, this->region,
                             this->host_row_pitch, this->host_slice_pitch)) {
    log_error("Buffer rect content difference found\n");
    return FAILURE;
  }

  if (this->host_m_2.Count(vv1) != tot_in_reg)
  {
    log_error("Buffer rect content difference found\n");
    return FAILURE;
  }

  err = clEnqueueReadBufferRect(this->m_queue, this->m_buffer, this->m_blocking,
                                this->buffer_origin_bytes,
                                this->host_origin_bytes,
                                this->region_bytes,
                                this->buffer_row_pitch_bytes,
                                this->buffer_slice_pitch_bytes,
                                this->host_row_pitch_bytes,
                                this->host_slice_pitch_bytes,
                                this->host_m_2.pData,
                                0, NULL, &event);

  if (err == CL_SUCCESS) {
    log_error("Calling clEnqueueReadBufferRect on a memory object created with the CL_MEM_HOST_WRITE_ONLY flag should not return CL_SUCCESS\n");
    err = FAILURE;
    return FAILURE;

  } else {
    log_info("Test succeeded\n\n");
    err = CL_SUCCESS;
  }

  return err;
}

template < class T >
cl_int cBuffer_check_mem_host_write_only< T >::update_host_mem_2()
{
  size_t global_work_size[3] = {0, 1, 1};
  global_work_size[0] = this->get_block_size_bytes();

  cl_event event, event_2;
  cl_int err = clEnqueueCopyBuffer(this->m_queue, this->m_buffer, this->m_buffer2, 0, 0,
                                   this->m_nNumber_elements* sizeof (T), 0, NULL, &event);
  test_error(err, "clEnqueueCopyBuffer error");

  this->host_m_2.Set_to_zero();
  err = clEnqueueReadBuffer(this->m_queue, this->m_buffer2, CL_TRUE, 0,
                            this->get_block_size_bytes(), this->host_m_2.pData,
                            1, &event, &event_2);
  test_error(err, "clEnqueueReadBuffer error");

  clWaitForEvents(1, &event_2);
  test_error(err, "clWaitForEvents error");

  err = clReleaseEvent(event_2);
  test_error(err, "clReleaseEvent error");

  err = clReleaseEvent(event);
  test_error(err, "clReleaseEvent error");
  return err;
}

template < class T >
cl_int cBuffer_check_mem_host_write_only< T >::verify_RW_Buffer_mapping()
{
  T vv2 = 0;
  this->host_m_2.Set_to(vv2);

  cl_event event;
  cl_int err = CL_SUCCESS;

  void *dataPtr;
  int size = this->get_block_size_bytes();
  dataPtr = clEnqueueMapBuffer(this->m_queue, this->m_buffer, this->m_blocking,
                               CL_MAP_WRITE,
                               0, size,
                               0, NULL, &event, &err);
  test_error(err, "clEnqueueMapBuffer error");

  if (!this->m_blocking) {
    err = clWaitForEvents(1, &event);
    test_error(err, "clWaitForEvents error");
  }

  err = clReleaseEvent(event);
  test_error(err, "clReleaseEvent error");

  update_host_mem_2();

  if ((this->buffer_mem_flag & CL_MEM_USE_HOST_PTR) && dataPtr != this->pHost_ptr){
    log_error("Mapped host pointer difference found\n");
    return FAILURE;
  }

  if(!this->host_m_2.Equal((T*)dataPtr, this->m_nNumber_elements)) {
    log_error("Buffer content difference found\n");
    return FAILURE;
  }

  err = clEnqueueUnmapMemObject(this->m_queue, this->m_buffer, dataPtr, 0,
                                nullptr, nullptr);
  test_error(err, "clEnqueueUnmapMemObject error");

  // test map read
  clEnqueueMapBuffer(this->m_queue, this->m_buffer, this->m_blocking,
                     CL_MAP_READ,
                     0, this->get_block_size_bytes(),
                     0, NULL, &event, &err);

  if (err == CL_SUCCESS) {
    log_error("Calling clEnqueueMapBuffer (CL_MAP_READ) on a memory object created with the MEM_HOST_WRITE_ONLY flag should not return CL_SUCCESS\n");
    err = FAILURE;

  } else {
    log_info("Test succeeded\n\n");
    err = CL_SUCCESS;
  }

  return err;
}

#endif
