//
// 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.
//
#include "allocation_fill.h"

#define BUFFER_CHUNK_SIZE 8*1024*1024
#define IMAGE_LINES 8

#include "harness/compat.h"

int fill_buffer_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, size_t size, MTdata d, cl_bool blocking_write) {
     size_t i, j;
  cl_uint *data;
  int error, result;
  cl_uint checksum_delta = 0;
  cl_event event;

  size_t size_to_use = BUFFER_CHUNK_SIZE;
  if (size_to_use > size)
    size_to_use = size;

  data = (cl_uint*)malloc(size_to_use);
  if (data == NULL) {
    log_error("Failed to malloc host buffer for writing into buffer.\n");
    return FAILED_ABORT;
  }
  for (i=0; i<size-size_to_use; i+=size_to_use) {
    // Put values in the data, and keep a checksum as we go along.
    for (j=0; j<size_to_use/sizeof(cl_uint); j++) {
      data[j] = genrand_int32(d);
      checksum_delta += data[j];
    }
    if (blocking_write) {
      error = clEnqueueWriteBuffer(*queue, mem, CL_TRUE, i, size_to_use, data, 0, NULL, NULL);
      result = check_allocation_error(context, device_id, error, queue);

      if (result == FAILED_ABORT) {
        print_error(error, "clEnqueueWriteBuffer failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        free(data);
        clReleaseMemObject(mem);
        return result;
      }
    } else {
      error = clEnqueueWriteBuffer(*queue, mem, CL_FALSE, i, size_to_use, data, 0, NULL, &event);
      result = check_allocation_error(context, device_id, error, queue);

      if (result == FAILED_ABORT) {
        print_error(error, "clEnqueueWriteBuffer failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        free(data);
        clReleaseMemObject(mem);
        return result;
      }

      error = clWaitForEvents(1, &event);
      result = check_allocation_error(context, device_id, error, queue, &event);

      if (result == FAILED_ABORT) {
        print_error(error, "clWaitForEvents failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseEvent(event);
        free(data);
        clReleaseMemObject(mem);
        return result;
      }

      clReleaseEvent(event);
    }
  }

  // Deal with any leftover bits
  if (i < size) {
    // Put values in the data, and keep a checksum as we go along.
    for (j=0; j<(size-i)/sizeof(cl_uint); j++) {
      data[j] = (cl_uint)genrand_int32(d);
      checksum_delta += data[j];
    }

    if (blocking_write) {
      error = clEnqueueWriteBuffer(*queue, mem, CL_TRUE, i, size-i, data, 0, NULL, NULL);
      result = check_allocation_error(context, device_id, error, queue);

      if (result == FAILED_ABORT) {
        print_error(error, "clEnqueueWriteBuffer failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseMemObject(mem);
        free(data);
        return result;
      }
    } else {
      error = clEnqueueWriteBuffer(*queue, mem, CL_FALSE, i, size-i, data, 0, NULL, &event);
      result = check_allocation_error(context, device_id, error, queue);

      if (result == FAILED_ABORT) {
        print_error(error, "clEnqueueWriteBuffer failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseMemObject(mem);
        free(data);
        return result;
      }

      error = clWaitForEvents(1, &event);
      result = check_allocation_error(context, device_id, error, queue, &event);

      if (result == FAILED_ABORT) {
        print_error(error, "clWaitForEvents failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseEvent(event);
        free(data);
        clReleaseMemObject(mem);
        return result;
      }

      clReleaseEvent(event);
    }
  }

  free(data);
  // Only update the checksum if this succeeded.
  checksum += checksum_delta;
  return SUCCEEDED;
}


int fill_image_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, size_t width, size_t height, MTdata d, cl_bool blocking_write) {
  size_t origin[3], region[3], j;
  int error, result;
  cl_uint *data;
  cl_uint checksum_delta = 0;
  cl_event event;

  size_t image_lines_to_use;
  image_lines_to_use = IMAGE_LINES;
  if (image_lines_to_use > height)
      image_lines_to_use = height;

  data = (cl_uint*)malloc(width*4*sizeof(cl_uint)*image_lines_to_use);
  if (data == NULL) {
    log_error("Failed to malloc host buffer for writing into image.\n");
    return FAILED_ABORT;
  }
  origin[0] = 0;
  origin[1] = 0;
  origin[2] = 0;
  region[0] = width;
  region[1] = image_lines_to_use;
  region[2] = 1;
  for (origin[1] = 0; origin[1] < height - image_lines_to_use; origin[1] += image_lines_to_use) {
    // Put values in the data, and keep a checksum as we go along.
    for (j=0; j<width*4*image_lines_to_use; j++) {
      data[j] = (cl_uint)genrand_int32(d);
      checksum_delta += data[j];
    }

    if (blocking_write) {
      error = clEnqueueWriteImage(*queue, mem, CL_TRUE, origin, region, 0, 0, data, 0, NULL, NULL);
      result = check_allocation_error(context, device_id, error, queue);

      if (result == FAILED_ABORT) {
        print_error(error, "clEnqueueWriteImage failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseMemObject(mem);
        free(data);
        return result;
      }
      result = clFinish(*queue);
      if (result != SUCCEEDED)
      {
        print_error(error, "clFinish failed after successful enquing filling buffer with data.");
        return result;
      }
    } else {
      error = clEnqueueWriteImage(*queue, mem, CL_FALSE, origin, region, 0, 0, data, 0, NULL, &event);
      result = check_allocation_error(context, device_id, error, queue);

      if (result == FAILED_ABORT) {
        print_error(error, "clEnqueueWriteImage failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseMemObject(mem);
        free(data);
        return result;
      }

      error = clWaitForEvents(1, &event);
      result = check_allocation_error(context, device_id, error, queue, &event);

      if (result == FAILED_ABORT) {
        print_error(error, "clWaitForEvents failed.");
      }

      if (result != SUCCEEDED) {
        clReleaseEvent(event);
        free(data);
        clReleaseMemObject(mem);
        return result;
      }

      clReleaseEvent(event);
    }
  }

  // Deal with any leftover bits
  if (origin[1] < height) {
    // Put values in the data, and keep a checksum as we go along.
    for (j=0; j<width*4*(height-origin[1]); j++) {
      data[j] = (cl_uint)genrand_int32(d);
      checksum_delta += data[j];
    }

    region[1] = height-origin[1];
    if(blocking_write) {
      error = clEnqueueWriteImage(*queue, mem, CL_TRUE, origin, region, 0, 0, data, 0, NULL, NULL);
      result = check_allocation_error(context, device_id, error, queue);

      if (result == FAILED_ABORT) {
        print_error(error, "clEnqueueWriteImage failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseMemObject(mem);
        free(data);
        return result;
      }
    } else {
      error = clEnqueueWriteImage(*queue, mem, CL_FALSE, origin, region, 0, 0, data, 0, NULL, &event);
      result = check_allocation_error(context, device_id, error, queue);

      if (result == FAILED_ABORT) {
        print_error(error, "clEnqueueWriteImage failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseMemObject(mem);
        free(data);
        return result;
      }

      error = clWaitForEvents(1, &event);
      result = check_allocation_error(context, device_id, error, queue, &event);

      if (result == FAILED_ABORT) {
        print_error(error, "clWaitForEvents failed.");
      }

      if (result != SUCCEEDED) {
        clFinish(*queue);
        clReleaseEvent(event);
        free(data);
        clReleaseMemObject(mem);
        return result;
      }

      clReleaseEvent(event);
    }
  }

  free(data);
  // Only update the checksum if this succeeded.
  checksum += checksum_delta;
  return SUCCEEDED;
}



int fill_mem_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, MTdata d, cl_bool blocking_write) {
  int error;
  cl_mem_object_type type;
  size_t size, width, height;

  error = clGetMemObjectInfo(mem, CL_MEM_TYPE, sizeof(type), &type, NULL);
  test_error_abort(error, "clGetMemObjectInfo failed for CL_MEM_TYPE.");

  if (type == CL_MEM_OBJECT_BUFFER) {
    error = clGetMemObjectInfo(mem, CL_MEM_SIZE, sizeof(size), &size, NULL);
    test_error_abort(error, "clGetMemObjectInfo failed for CL_MEM_SIZE.");
    return fill_buffer_with_data(context, device_id, queue, mem, size, d, blocking_write);
  } else if (type == CL_MEM_OBJECT_IMAGE2D) {
    error = clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width, NULL);
    test_error_abort(error, "clGetImageInfo failed for CL_IMAGE_WIDTH.");
    error = clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL);
    test_error_abort(error, "clGetImageInfo failed for CL_IMAGE_HEIGHT.");
    return fill_image_with_data(context, device_id, queue, mem, width, height, d, blocking_write);
  }

  log_error("Invalid CL_MEM_TYPE: %d\n", type);
  return FAILED_ABORT;
}



