//===-- LanguageRuntime.cpp - Kernel language runtime API implementation --===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LANGUAGE
#error This file should be included, or used, with a LANGUAGE macro set.
#endif

// Rename the generic runtime API before declaring or defining language symbols.
// clang-format off
#include "DefineLanguageNames.inc"
#include "LanguageErrors.h"
#include "LanguageRuntime.h"
// clang-format on

#include "LanguageUtils.h"
#include "State.h"
#include "Stream.h"
#include "Types.h"

#include "OffloadAPI.h"

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace llvm::offload;

Error_t Malloc(void **DevPtr, size_t Size) {
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  ol_device_handle_t Device = ThreadState.getDefaultDevice();
  ol_result_t Result = olMemAlloc(Device, OL_ALLOC_TYPE_DEVICE, Size, DevPtr);
  return convertAndSetLastError(Result);
}

Error_t Free(void *DevPtr) {
  ol_result_t Result = olMemFree(DevPtr);
  return convertAndSetLastError(Result);
}

Error_t Memcpy(void *Dst, const void *Src, size_t Size, MemcpyKind Kind) {
  StateTy &State = StateTy::get();
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  ol_queue_handle_t Queue = ThreadState.getDefaultQueue();

  ol_result_t Result;
  switch (Kind) {
  case MemcpyHostToHost: {
    ol_device_handle_t Host = State.getHostDevice();
    Result = olMemcpy(nullptr, Dst, Host, const_cast<void *>(Src), Host, Size);
    break;
  }
  case MemcpyHostToDevice: {
    ol_device_handle_t Device = ThreadState.getDefaultDevice();
    ol_device_handle_t Host = State.getHostDevice();
    Result = olMemcpy(Queue, Dst, Device, const_cast<void *>(Src), Host, Size);
    break;
  }
  case MemcpyDeviceToHost: {
    ol_device_handle_t Device = ThreadState.getDefaultDevice();
    ol_device_handle_t Host = State.getHostDevice();

    Result = olMemcpy(Queue, Dst, Host, const_cast<void *>(Src), Device, Size);
    break;
  }
  case MemcpyDeviceToDevice: {
    ol_device_handle_t Device = ThreadState.getDefaultDevice();

    Result =
        olMemcpy(Queue, Dst, Device, const_cast<void *>(Src), Device, Size);
    break;
  }
  case MemcpyDefault:
    FATAL_UNIMPLEMENTED("MemcpyDefault is not implemented yet");
  };

  if (Result != OL_SUCCESS)
    return convertAndSetLastError(Result);

  Result = olSyncQueue(Queue);
  return convertAndSetLastError(Result);
}

Error_t DeviceSynchronize() {
  // TODO: This is not correct. We likely want to pipe this through to the
  // plugins.
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  ol_queue_handle_t Queue = ThreadState.getDefaultQueue();
  ol_result_t Result = olSyncQueue(Queue);
  return convertAndSetLastError(Result);
}

Error_t GetDevice(int *DeviceNo) {
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  ol_device_handle_t Device = ThreadState.getDevice(DeviceNo);
  if (!Device)
    return setLastError(ErrorInvalidDevice);
  return setLastError(Success);
}

Error_t GetDeviceCount(int *Count) {
  *Count = StateTy::get().getDeviceCount();
  return setLastError(Success);
}

Error_t SetDevice(int DeviceNo) {
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  ol_device_handle_t Device = ThreadState.setDefaultDevice(DeviceNo);
  if (!Device)
    return setLastError(ErrorInvalidDevice);
  assert(Device == ThreadState.getDefaultDevice() &&
         "Set Device is not Default Device");
  return setLastError(Success);
}

Error_t HostAlloc(void **Ptr, size_t Size, unsigned int Flags) {
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  ol_device_handle_t Device = ThreadState.getDefaultDevice();
  ol_result_t Result = olMemAllocHost(Device, Size, Ptr);
  return convertAndSetLastError(Result);
}

Error_t MallocHost(void **Ptr, size_t Size) {
  return HostAlloc(Ptr, Size, /* HostAllocDefault */ 0);
}

Error_t FreeHost(void *Ptr) {
  ol_result_t Result = olMemFree(Ptr);
  return convertAndSetLastError(Result);
}

Error_t GetDeviceProperties(DeviceProp_t *DeviceProp, int DeviceNo) {
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  ol_device_handle_t Device = ThreadState.getDefaultDevice();
  size_t NameSize = 0;
  olGetDeviceInfoSize(Device, OL_DEVICE_INFO_NAME, &NameSize);
  assert(NameSize <= sizeof(DeviceProp->name) &&
         "Device name is too long for DeviceProp_t");
  olGetDeviceInfo(Device, OL_DEVICE_INFO_NAME, NameSize, &DeviceProp->name[0]);
  olGetDeviceInfo(Device, OL_DEVICE_INFO_GLOBAL_MEM_SIZE, sizeof(size_t),
                  &DeviceProp->totalGlobalMem);
  olGetDeviceInfo(Device, OL_DEVICE_INFO_NUM_COMPUTE_UNITS, sizeof(uint32_t),
                  &DeviceProp->multiProcessorCount);
  olGetDeviceInfo(Device, OL_DEVICE_INFO_NUM_LANES, sizeof(uint32_t),
                  &DeviceProp->warpSize);
  return setLastError(Success);
}

Error_t StreamCreate(Stream_t *Stream) {
  if (!Stream)
    return setLastError(ErrorInvalidValue);

  StateTy &State = StateTy::get();
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  StreamTy *StreamObj = nullptr;
  ol_result_t Result = State.createStream(
      ThreadState.getDefaultDevice(), QueueKind::ExplicitBlocking, &StreamObj);
  if (Result == OL_SUCCESS)
    *Stream = toLanguageStream(StreamObj);
  return convertAndSetLastError(Result);
}

Error_t StreamCreateWithFlags(Stream_t *Stream, unsigned int Flags) {
  if (!Stream)
    return setLastError(ErrorInvalidValue);

  if (Flags == StreamDefault)
    return StreamCreate(Stream);
  if (Flags != StreamNonBlocking)
    return setLastError(ErrorInvalidValue);

  StateTy &State = StateTy::get();
  ThreadStateTy &ThreadState = ThreadStateTy::get();
  StreamTy *StreamObj = nullptr;
  ol_result_t Result =
      State.createStream(ThreadState.getDefaultDevice(),
                         QueueKind::ExplicitNonBlocking, &StreamObj);
  if (Result == OL_SUCCESS)
    *Stream = toLanguageStream(StreamObj);
  return convertAndSetLastError(Result);
}

Error_t StreamDestroy(Stream_t Stream) {
  if (!Stream)
    return setLastError(ErrorInvalidValue);
  ol_result_t Result = StateTy::get().destroyStream(toInternalStream(Stream));
  return convertAndSetLastError(Result);
}

Error_t StreamSynchronize(Stream_t Stream) {
  ol_queue_handle_t Queue;
  Error_t Err = getQueueFromStream(Stream, &Queue);
  if (Err != Success)
    return setLastError(Err);
  ol_result_t Result = olSyncQueue(Queue);
  return convertAndSetLastError(Result);
}

#include "UndefineLanguageNames.inc"
