/*
* Copyright (c) 2021, The Fuchsia Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

#include "magma_fd.h"

#include <assert.h>
#include <i915_drm.h>
#include <lib/magma/magma.h>
#include <magma_intel_gen_defs.h>

#include <map>
#include <mutex>

namespace {

struct FakeFdMap {
  std::map<int32_t, uintptr_t> map;
  std::mutex mutex;
  int32_t next_fd = -1;
};

FakeFdMap* gMap; // never destroyed
std::once_flag gOnceFlag;

} // namespace

int get_magma_fd_for_device(uintptr_t device) {
  std::call_once(gOnceFlag, []() { gMap = new FakeFdMap; });

  std::lock_guard<std::mutex> lock(gMap->mutex);

  if (gMap->next_fd < 0)
    gMap->next_fd = 1;

  int fd = gMap->next_fd++;

  // Roll over fails because we never release fds
  assert(gMap->map.find(fd) == gMap->map.end());

  gMap->map[fd] = device;
  return fd;
}

uintptr_t get_device_for_magma_fd(int fd) {
  assert(gMap);
  std::lock_guard<std::mutex> lock(gMap->mutex);

  auto iter = gMap->map.find(fd);
  if (iter == gMap->map.end())
    return 0;

  uintptr_t device = iter->second;
  return device;
}

bool query_magma_fd(int fd, int32_t param, uint32_t* value_out) {
  magma_device_t device = get_device_for_magma_fd(fd);
  if (!device)
    return false;

  magma_status_t status;
  uint64_t val64;

  switch (param) {
    case I915_PARAM_HAS_BSD: // 1st video command streamer instance
    case I915_PARAM_HAS_VEBOX:
    case I915_PARAM_HAS_ALIASING_PPGTT:
      *value_out = 1;
      return true;

    case I915_PARAM_HAS_BSD2: // 2nd video command streamer instance
    case 42: //I915_PARAM_HAS_HUC
    case I915_PARAM_REVISION:
      *value_out = 0;
      return true;

    case I915_PARAM_CHIPSET_ID:
      status = magma_device_query(device, MAGMA_QUERY_DEVICE_ID, nullptr, &val64);
      if (status != MAGMA_STATUS_OK)
        return false;
      *value_out = static_cast<uint32_t>(val64);
      return true;

    case I915_PARAM_EU_TOTAL:
    case I915_PARAM_SUBSLICE_TOTAL:
      status = magma_device_query(device, kMagmaIntelGenQuerySubsliceAndEuTotal, nullptr, &val64);
      if (status != MAGMA_STATUS_OK)
        return false;
      *value_out = (param == I915_PARAM_EU_TOTAL) ? static_cast<uint32_t>(val64) : val64 >> 32;
      return true;

    default:
      return false;
  }
}
