/*
 *  Identify a POCL platform and device ID for running autopkgtests.
 */

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#define CL_MINIMUM_OPENCL_VERSION 120
#define CL_TARGET_OPENCL_VERSION 120
#define CL_CL_1_2_DEFAULT_BUILD

#include <CL/opencl.h>

static const cl_uint MAX_PLATFORMS = 128;
static const cl_uint MAX_DEVICES = 128;
static const size_t MAX_PLATFORM_NAME_LEN = 4096;
static const char POCL_NAME[] = "Portable Computing Language";

int main(int argc, char ** argv)
{
  cl_uint num_platforms = 0;
  cl_platform_id platforms[MAX_PLATFORMS];
  cl_int status = clGetPlatformIDs(MAX_PLATFORMS, platforms, &num_platforms);
  if (status != CL_SUCCESS)
  {
    fprintf(stderr, "Failed to query OpenCL platforms.\n");
    return 1;
  }
  num_platforms = num_platforms < MAX_PLATFORMS ? num_platforms : MAX_PLATFORMS;
  if (num_platforms < 1)
  {
    fprintf(stderr, "Found no OpenCL platforms.\n");
    return 1;
  }

  char platform_name[MAX_PLATFORM_NAME_LEN];
  size_t platform_name_len = 0;
  bool pocl_platform_found = false;
  cl_uint platform_idx = MAX_PLATFORMS;
  for (cl_uint i = 0; i < num_platforms; ++i)
  {
    status = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, MAX_PLATFORM_NAME_LEN-1, platform_name, &platform_name_len);
    if (status != CL_SUCCESS)
    {
      fprintf(stderr, "Failed to get name for OpenCL platform number %u.\n", i);
      return 1;
    }
    platform_name[platform_name_len < MAX_PLATFORM_NAME_LEN - 1 ? platform_name_len : MAX_PLATFORM_NAME_LEN - 1] = '\0';
    if (strcmp(platform_name, POCL_NAME) == 0)
    {
      platform_idx = i;
      pocl_platform_found = true;
      break;
    }
  }

  if (!pocl_platform_found)
  {
    fprintf(stderr, "Could not find the POCL platform.\n");
    return 1;
  }

  
  cl_device_id devices[MAX_DEVICES];
  cl_uint num_devices = 0;
  cl_uint device_idx = MAX_DEVICES;
  status = clGetDeviceIDs(platforms[platform_idx], CL_DEVICE_TYPE_CPU, MAX_DEVICES, devices, &num_devices);
  if (status != CL_SUCCESS)
  {
    fprintf(stderr, "Failed to query OpenCL CPU devices for platform.\n");
    return 1;
  }
  num_devices = num_devices < MAX_DEVICES ? num_devices : MAX_DEVICES;

  if (num_devices < 1)
  {
    fprintf(stderr, "Failed to find any devices on platform.\n");
    return 1;
  }

  device_idx = 0; // We default to running on the first POCL device.

  printf("%u %u\n", platform_idx, device_idx);
  return 0;
}
