//===-- 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_context_handle_t Context = StateTy::get().getContext();
  ol_result_t Result =
      olMemAlloc(Context, Device, OL_ALLOC_TYPE_DEVICE, Size, DevPtr);
  return convertAndSetLastError(Result);
}

Error_t Free(void *DevPtr) {
  ol_context_handle_t Context = StateTy::get().getContext();
  ol_result_t Result = olMemFree(Context, 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_context_handle_t Context = StateTy::get().getContext();
  ol_result_t Result = olMemAllocHost(Context, 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_context_handle_t Context = StateTy::get().getContext();
  ol_result_t Result = olMemFree(Context, 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"
