//===--- Level Zero Target RTL 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
//
//===----------------------------------------------------------------------===//
//
//  Level Zero Driver abstraction.
//
//===----------------------------------------------------------------------===//

#include "L0Driver.h"
#include "L0Context.h"
#include "L0Plugin.h"

namespace llvm::omp::target::plugin {

/// Compose a driver version string from the packed value reported by
/// zeDriverGetProperties. Used when zeIntelGetDriverVersionString is missing.
static Expected<std::string>
getDriverVersionFromProperties(ze_driver_handle_t zeDriver) {
  ze_driver_properties_t DriverProperties{};
  DriverProperties.stype = ZE_STRUCTURE_TYPE_DRIVER_PROPERTIES;
  CALL_ZE_RET_ERROR(zeDriverGetProperties, zeDriver, &DriverProperties);

  const uint32_t PackedVersion = DriverProperties.driverVersion;
  return std::to_string((PackedVersion & 0xFF000000) >> 24) + "." +
         std::to_string((PackedVersion & 0x00FF0000) >> 16) + "." +
         std::to_string(PackedVersion & 0x0000FFFF);
}

L0DriverTy::L0DriverTy(LevelZeroPluginTy &Plugin, ze_driver_handle_t zeDriver,
                       int32_t DriverId)
    : Plugin(Plugin), zeDriver(zeDriver), DriverId(DriverId) {}

L0DriverTy::~L0DriverTy() = default;

Expected<std::string> L0DriverTy::tryGetIntelDriverVersion() {
  size_t VersionSize = 0;
  CALL_ZE_RET_ERROR(IntelGetDriverVersionString, zeDriver, nullptr,
                    &VersionSize);
  std::string Version(VersionSize, '\0');
  CALL_ZE_RET_ERROR(IntelGetDriverVersionString, zeDriver, Version.data(),
                    &VersionSize);
  if (!Version.empty() && Version.back() == '\0')
    Version.pop_back();
  return Version;
}

Error L0DriverTy::init() {
  auto CleanupOnError = [&]() {
    if (zeContext) {
      zeContextDestroy(zeContext);
      zeContext = nullptr;
    }
  };
  CALL_ZE_RET_ERROR(zeDriverGetApiVersion, zeDriver, &APIVersion);
  ODBG(OLDT_Init) << "Driver API version is "
                  << llvm::format(PRIx32, APIVersion);

  ze_context_desc_t Desc{ZE_STRUCTURE_TYPE_CONTEXT_DESC, nullptr, 0};
  CALL_ZE_RET_ERROR(zeContextCreate, zeDriver, &Desc, &zeContext);

  const auto &Options = Plugin.getOptions();
  bool UseCounterBasedEvents = Options.CommandMode == CommandModeTy::InOrder ||
                               Options.CommandMode == CommandModeTy::Sync;
  if (UseCounterBasedEvents)
    ODBG(OLDT_Init) << "Using counter-based events for "
                    << (Options.CommandMode == CommandModeTy::InOrder
                            ? "InOrder"
                            : "Sync")
                    << " command mode";

  if (auto Err = EventPool.init(zeContext, UseCounterBasedEvents,
                                /* Flags */ 0)) {
    CleanupOnError();
    return Err;
  }
  if (auto Err = HostMemAllocator.initHostPool(*this, Plugin.getOptions(),
                                               zeContext)) {
    if (auto DeinitErr = EventPool.deinit())
      Err = joinErrors(std::move(Err), std::move(DeinitErr));
    CleanupOnError();
    return Err;
  }

  ODBG(OLDT_Init) << "APIs supported by the context with dlopen: ";
  ODBG(OLDT_Init) << "  zeCommandListAppendLaunchKernelWithArguments: "
                  << (LaunchKernelWithArguments.available() ? "yes" : "no");
  ODBG(OLDT_Init) << "  zeCommandListAppendHostFunction: "
                  << (CommandListAppendHostFunction.available() ? "yes" : "no");
  ODBG(OLDT_Init) << "  zeDriverGetDefaultContext: "
                  << (DriverGetDefaultContext.available() ? "yes" : "no");

  LaunchKernelWithArguments.loadExperimental(
      zeDriver, "zeCommandListAppendLaunchKernelWithArguments");

  CommandListAppendHostFunction.loadExperimental(
      zeDriver, "zeCommandListAppendHostFunction");
  if (!CommandListAppendHostFunction)
    // Try again with a name used in compute runtime 25.35 to 25.48
    CommandListAppendHostFunction.loadExperimental(
        zeDriver, "zexCommandListAppendHostFunction");

  DriverGetDefaultContext.loadExperimental(zeDriver,
                                           "zeDriverGetDefaultContext");
  IntelGetDriverVersionString.loadExperimental(zeDriver,
                                               "zeIntelGetDriverVersionString");

  ODBG(OLDT_Init) << "APIs supported by the context with added extensions: ";
  ODBG(OLDT_Init) << "  zeCommandListAppendLaunchKernelWithArguments: "
                  << (LaunchKernelWithArguments.available() ? "yes" : "no");
  ODBG(OLDT_Init) << "  zeCommandListAppendHostFunction: "
                  << (CommandListAppendHostFunction.available() ? "yes" : "no");
  ODBG(OLDT_Init) << "  zeDriverGetDefaultContext: "
                  << (DriverGetDefaultContext.available() ? "yes" : "no");

  auto DriverVersionOrErr = IntelGetDriverVersionString.available()
                                ? tryGetIntelDriverVersion()
                                : getDriverVersionFromProperties(zeDriver);
  if (!DriverVersionOrErr)
    return DriverVersionOrErr.takeError();
  DriverVersion = std::move(*DriverVersionOrErr);
  ODBG(OLDT_Init) << "Driver version is " << DriverVersion;

  DefaultUserCtx = std::make_unique<LevelZeroPluginContextTy>(
      Plugin, /*Devices=*/llvm::ArrayRef<GenericDeviceTy *>{}, zeDriver,
      zeContext, /*OwnsZeContext=*/false);

  return Plugin::success();
}

Error L0DriverTy::deinit() {
  // Release the default context (drains its queue cache) before zeContext.
  if (DefaultUserCtx) {
    if (auto Err = DefaultUserCtx->deinit())
      return Err;
    DefaultUserCtx.reset();
  }
  if (auto Err = EventPool.deinit())
    return Err;
  if (auto Err = HostMemAllocator.deinit())
    return Err;
  if (zeContext)
    CALL_ZE_RET_ERROR(zeContextDestroy, zeContext);
  return Plugin::success();
}

} // namespace llvm::omp::target::plugin
