// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "vaapi_utils.h"

#include <fuchsia/media/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/zx/channel.h>
#include <zircon/assert.h>

#include <filesystem>
#include <type_traits>
#include <utility>

#include <fbl/no_destructor.h>
#include <safemath/safe_conversions.h>
#include <va/va_magma.h>

#include "chromium_utils.h"
namespace {
std::unique_ptr<VADisplayWrapper> display_wrapper;
}

static void libva_error_callback(void* user_context, const char* message) {
  FX_SLOG(ERROR, "libva error", FX_KV("error_message", message));
}

static void libva_info_callback(void* user_context, const char* message) {
  FX_SLOG(INFO, "libva message", FX_KV("message", message));
}

// static
bool VADisplayWrapper::InitializeSingleton(uint64_t required_vendor_id) {
  ZX_ASSERT(!display_wrapper);

  auto new_display_wrapper = std::make_unique<VADisplayWrapper>();

  for (auto& p : std::filesystem::directory_iterator("/dev/class/gpu")) {
    {
      zx::channel local, remote;
      zx_status_t zx_status = zx::channel::create(0 /*flags*/, &local, &remote);
      ZX_ASSERT(zx_status == ZX_OK);
      zx_status = fdio_service_connect(p.path().c_str(), remote.release());
      ZX_ASSERT(zx_status == ZX_OK);
      magma_status_t status =
          magma_device_import(local.release(), &new_display_wrapper->magma_device_);
      ZX_ASSERT(status == MAGMA_STATUS_OK);
      if (status != MAGMA_STATUS_OK)
        continue;
    }
    {
      uint64_t vendor_id;
      magma_status_t magma_status = magma_device_query(new_display_wrapper->magma_device_,
                                                       MAGMA_QUERY_VENDOR_ID, nullptr, &vendor_id);
      if (magma_status == MAGMA_STATUS_OK && vendor_id == required_vendor_id) {
        break;
      }
    }

    magma_device_release(new_display_wrapper->magma_device_);
    new_display_wrapper->magma_device_ = {};
  }

  if (!new_display_wrapper->magma_device_)
    return false;

  if (!new_display_wrapper->Initialize()) {
    magma_device_release(new_display_wrapper->magma_device_);
    return false;
  }
  display_wrapper = std::move(new_display_wrapper);
  return true;
}

// static
bool VADisplayWrapper::InitializeSingletonForTesting() {
  auto new_display_wrapper = std::make_unique<VADisplayWrapper>();
  if (!new_display_wrapper->Initialize())
    return false;
  display_wrapper = std::move(new_display_wrapper);
  return true;
}

// static
bool VADisplayWrapper::DestroySingleton() {
  if (display_wrapper->Destroy()) {
    magma_device_release(display_wrapper->magma_device_);
    display_wrapper.reset();
    return true;
  }

  return false;
}

bool VADisplayWrapper::Initialize() {
  display_ = vaGetDisplayMagma(magma_device_);
  if (!display_)
    return false;

  vaSetErrorCallback(display_, libva_error_callback, nullptr);
  vaSetInfoCallback(display_, libva_info_callback, nullptr);

  int major_ver, minor_ver;
  VAStatus va_status = vaInitialize(display_, &major_ver, &minor_ver);
  if (va_status != VA_STATUS_SUCCESS) {
    return false;
  }
  return true;
}

bool VADisplayWrapper::Destroy() {
  VAStatus va_status = vaTerminate(display_);

  return (va_status == VA_STATUS_SUCCESS);
}

// static
VADisplayWrapper* VADisplayWrapper::GetSingleton() { return display_wrapper.get(); }

VASurface::VASurface(VASurfaceID va_surface_id, const gfx::Size& size, unsigned int format,
                     ReleaseCB release_cb)
    : va_surface_id_(va_surface_id),
      size_(size),
      format_(format),
      release_cb_(std::move(release_cb)) {
  DCHECK(release_cb_);
}

VASurface::~VASurface() { std::move(release_cb_)(va_surface_id_); }

static bool SupportsEntrypointForProfile(VAProfile profile, VAEntrypoint required_entrypoint) {
  VADisplay display = VADisplayWrapper::GetSingleton()->display();
  size_t max_entrypoints = safemath::checked_cast<size_t>(vaMaxNumEntrypoints(display));

  int num_entrypoints = 0;
  std::vector<VAEntrypoint> entrypoints(max_entrypoints);

  VAStatus status =
      vaQueryConfigEntrypoints(display, profile, entrypoints.data(), &num_entrypoints);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaQueryConfigEntrypoints failed", FX_KV("error_str", vaErrorStr(status)));
    return false;
  }

  int vld_entrypoint;
  for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) {
    if (entrypoints[vld_entrypoint] == required_entrypoint) {
      return true;
    }
  }

  return false;
}

static bool SupportsAttribsForProfile(VAProfile profile, VAEntrypoint required_entrypoint,
                                      const std::vector<VAConfigAttrib>& required_attribs) {
  VADisplay display = VADisplayWrapper::GetSingleton()->display();
  std::vector<VAConfigAttrib> config_attrib = required_attribs;
  for (size_t i = 0; i < config_attrib.size(); i += 1) {
    config_attrib[i].value = 0u;
  }

  VAStatus status =
      vaGetConfigAttributes(display, profile, required_entrypoint, config_attrib.data(),
                            safemath::checked_cast<int>(config_attrib.size()));
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaGetConfigAttributes failed", FX_KV("error_str", vaErrorStr(status)));
    return false;
  }

  for (size_t i = 0; i < required_attribs.size(); i += 1) {
    if ((config_attrib[i].type != required_attribs[i].type) ||
        ((config_attrib[i].value & required_attribs[i].value) != required_attribs[i].value)) {
      using UnderlyingType = std::underlying_type_t<decltype(required_attribs[i].type)>;
      FX_SLOG(DEBUG, "Unsupported attribute",
              FX_KV("type", static_cast<UnderlyingType>(required_attribs[i].type)),
              FX_KV("required_value", required_attribs[i].value),
              FX_KV("actual_value", config_attrib[i].value));
      return false;
    }
  }

  return true;
}

bool SupportsProfile(VAProfile profile, VAEntrypoint required_entrypoint,
                     const std::vector<VAConfigAttrib>& required_attribs) {
  if (!SupportsEntrypointForProfile(profile, required_entrypoint)) {
    return false;
  }

  if (!SupportsAttribsForProfile(profile, required_entrypoint, required_attribs)) {
    return false;
  }

  return true;
}

std::optional<ProfileDescription> GetProfileDescription(
    const VAProfile& profile, VAEntrypoint required_entrypoint,
    std::vector<VAConfigAttrib>& required_attribs) {
  VADisplay display = VADisplayWrapper::GetSingleton()->display();

  if (!SupportsProfile(profile, required_entrypoint, required_attribs)) {
    return std::nullopt;
  }

  VAConfigID config_id;
  VAStatus status =
      vaCreateConfig(display, profile, required_entrypoint, required_attribs.data(),
                     safemath::checked_cast<int>(required_attribs.size()), &config_id);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaCreateConfig failed", FX_KV("error_str", vaErrorStr(status)));
    return std::nullopt;
  }
  ScopedContextID scoped_context(config_id);

  unsigned int num_attribs = 0;
  status = vaQuerySurfaceAttributes(display, config_id, nullptr, &num_attribs);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaQuerySurfaceAttributes failed", FX_KV("error_str", vaErrorStr(status)));
    return std::nullopt;
  }

  std::vector<VASurfaceAttrib> attrib_list(safemath::checked_cast<size_t>(num_attribs));
  status = vaQuerySurfaceAttributes(display, profile, attrib_list.data(), &num_attribs);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaQuerySurfaceAttributes failed", FX_KV("error_str", vaErrorStr(status)));
    return std::nullopt;
  }

  ProfileDescription description;
  description.profile = profile;
  description.entrypoint = required_entrypoint;
  for (const auto& attrib : attrib_list) {
    if (attrib.type == VASurfaceAttribMinWidth) {
      ZX_DEBUG_ASSERT(!description.min_width.has_value());
      description.min_width = attrib.value.value.i;
    } else if (attrib.type == VASurfaceAttribMaxWidth) {
      ZX_DEBUG_ASSERT(!description.max_width.has_value());
      description.max_width = attrib.value.value.i;
    } else if (attrib.type == VASurfaceAttribMinHeight) {
      ZX_DEBUG_ASSERT(!description.min_height.has_value());
      description.min_height = attrib.value.value.i;
    } else if (attrib.type == VASurfaceAttribMaxHeight) {
      ZX_DEBUG_ASSERT(!description.max_height.has_value());
      description.max_height = attrib.value.value.i;
    }
  }

  return description;
}

static std::vector<ProfileDescription> H264DecoderDescriptions() {
  std::vector<ProfileDescription> descriptions;

  std::vector<VAConfigAttrib> attribs = {
      {.type = VAConfigAttribRTFormat, .value = VA_RT_FORMAT_YUV420},
  };

  // Currently we only support the |VAProfileH264High| profile
  auto high_profile_description =
      GetProfileDescription(VAProfileH264High, VAEntrypointVLD, attribs);

  if (high_profile_description.has_value()) {
    descriptions.push_back(high_profile_description.value());
  }

  return descriptions;
}

static std::vector<ProfileDescription> VP9DecoderDescriptions() {
  std::vector<ProfileDescription> descriptions;

  std::vector<VAConfigAttrib> attribs = {
      {.type = VAConfigAttribRTFormat, .value = VA_RT_FORMAT_YUV420},
  };

  // Currently we only support the |VAProfileVP9Profile0| profile
  auto profile0_description = GetProfileDescription(VAProfileVP9Profile0, VAEntrypointVLD, attribs);

  if (profile0_description.has_value()) {
    descriptions.push_back(profile0_description.value());
  }

  return descriptions;
}

static bool SupportsH264Encoder() {
  std::vector<VAConfigAttrib> attribs = {
      {.type = VAConfigAttribRTFormat, .value = VA_RT_FORMAT_YUV420},
  };

  return SupportsProfile(VAProfileH264High, VAEntrypointEncSliceLP, attribs);
}

std::vector<VAProfile> GetHardwareSupportedProfiles() {
  VADisplay display = VADisplayWrapper::GetSingleton()->display();
  size_t max_num_profiles = safemath::checked_cast<size_t>(vaMaxNumProfiles(display));

  std::vector<VAProfile> supported_profiles(max_num_profiles, VAProfileNone);
  int num_profiles = 0;
  VAStatus status = vaQueryConfigProfiles(display, supported_profiles.data(), &num_profiles);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaQueryConfigProfiles failed", FX_KV("error_str", vaErrorStr(status)));
    return {};
  }

  supported_profiles.resize(safemath::checked_cast<size_t>(num_profiles));
  return supported_profiles;
}

static bool SupportsJPEGDecoder() {
  std::vector<VAConfigAttrib> attribs = {
      {.type = VAConfigAttribRTFormat, .value = VA_RT_FORMAT_YUV420},
  };

  return SupportsProfile(VAProfileJPEGBaseline, VAEntrypointVLD, attribs);
}

std::vector<fuchsia::mediacodec::CodecDescription> GetDeprecatedCodecList() {
  std::vector<fuchsia::mediacodec::CodecDescription> descriptions;

  if (SupportsJPEGDecoder()) {
    fuchsia::mediacodec::CodecDescription description;
    description.codec_type = fuchsia::mediacodec::CodecType::DECODER;
    description.mime_type = "video/x-motion-jpeg";
    descriptions.push_back(std::move(description));
  }

  if (!H264DecoderDescriptions().empty()) {
    fuchsia::mediacodec::CodecDescription description;
    description.codec_type = fuchsia::mediacodec::CodecType::DECODER;
    description.mime_type = "video/h264";
    descriptions.push_back(std::move(description));
  }

  if (!VP9DecoderDescriptions().empty()) {
    fuchsia::mediacodec::CodecDescription description;
    description.codec_type = fuchsia::mediacodec::CodecType::DECODER;
    description.mime_type = "video/vp9";
    descriptions.push_back(std::move(description));
  }

  if (SupportsH264Encoder()) {
    fuchsia::mediacodec::CodecDescription description;
    description.codec_type = fuchsia::mediacodec::CodecType::ENCODER;
    description.mime_type = "video/h264";
    descriptions.push_back(std::move(description));
  }

  return descriptions;
}

using ProfileMapType = std::map<fuchsia::media::CodecProfile, VAProfile>;
static ProfileMapType GetCodecProfileTranslation() {
  static const fbl::NoDestructor<ProfileMapType> kCodecProfileToVaProfileMap({
      {fuchsia::media::CodecProfile::H264PROFILE_BASELINE, VAProfileH264Baseline},
      {fuchsia::media::CodecProfile::H264PROFILE_MAIN, VAProfileH264Main},
      {fuchsia::media::CodecProfile::H264PROFILE_HIGH, VAProfileH264High},
      {fuchsia::media::CodecProfile::VP9PROFILE_PROFILE0, VAProfileVP9Profile0},
      {fuchsia::media::CodecProfile::VP9PROFILE_PROFILE1, VAProfileVP9Profile1},
      {fuchsia::media::CodecProfile::VP9PROFILE_PROFILE2, VAProfileVP9Profile2},
      {fuchsia::media::CodecProfile::VP9PROFILE_PROFILE3, VAProfileVP9Profile3},
  });

  return *kCodecProfileToVaProfileMap;
}

using VaProfileMapType = std::map<VAProfile, fuchsia::media::CodecProfile>;
static VaProfileMapType GetVaProfileTranslation() {
  static const fbl::NoDestructor<VaProfileMapType> kVaProfileToMap({
      {VAProfileH264Baseline, fuchsia::media::CodecProfile::H264PROFILE_BASELINE},
      {VAProfileH264Main, fuchsia::media::CodecProfile::H264PROFILE_MAIN},
      {VAProfileH264High, fuchsia::media::CodecProfile::H264PROFILE_HIGH},
      {VAProfileVP9Profile0, fuchsia::media::CodecProfile::VP9PROFILE_PROFILE0},
      {VAProfileVP9Profile1, fuchsia::media::CodecProfile::VP9PROFILE_PROFILE1},
      {VAProfileVP9Profile2, fuchsia::media::CodecProfile::VP9PROFILE_PROFILE2},
      {VAProfileVP9Profile3, fuchsia::media::CodecProfile::VP9PROFILE_PROFILE3},
  });

  return *kVaProfileToMap;
}

// TODO(https://fxbug.dev/42073599): Remove [[maybe_unused]] once used, or potentially remove the method if no
// longer expect to need to convert the other direction.
[[maybe_unused]] static VAProfile CodecProfileToVaProfile(fuchsia::media::CodecProfile profile) {
  const auto& profile_map = GetCodecProfileTranslation();
  const auto& profile_itr = profile_map.find(profile);

  if (profile_itr != profile_map.end()) {
    return profile_itr->second;
  }

  return VAProfileNone;
}

static fuchsia::media::CodecProfile VaProfileToCodecProfile(VAProfile profile) {
  const auto& profile_map = GetVaProfileTranslation();
  const auto& profile_itr = profile_map.find(profile);

  if (profile_itr != profile_map.end()) {
    return profile_itr->second;
  }

  return fuchsia::media::CodecProfile::Unknown();
}

std::vector<fuchsia::mediacodec::DetailedCodecDescription> GetCodecDescriptions() {
  std::vector<fuchsia::mediacodec::DetailedCodecDescription> codec_descriptions;

  fit::function<void(const std::string&, const std::vector<ProfileDescription>&)>
      add_decoder_profiles = [&codec_descriptions](
                                 const std::string& mime_type,
                                 const std::vector<ProfileDescription>& profile_descriptions) {
        fuchsia::mediacodec::DetailedCodecDescription codec_description;
        codec_description.set_codec_type(fuchsia::mediacodec::CodecType::DECODER);
        codec_description.set_mime_type(mime_type);
        codec_description.set_is_hw(true);

        // Iterate over each of the |ProfileDescription| and add the corresponding
        // |DecoderProfileDescription| to the list of supported profiles.
        std::vector<fuchsia::mediacodec::DecoderProfileDescription> decoder_descriptions;
        for (const auto& profile_description : profile_descriptions) {
          fuchsia::mediacodec::DecoderProfileDescription decoder_description;

          auto codec_profile = VaProfileToCodecProfile(profile_description.profile);
          if (codec_profile.IsUnknown()) {
            FX_SLOG(ERROR, "Unknown translation from VAProfile to CodecProfile",
                    FX_KV("va_profile", safemath::strict_cast<std::underlying_type_t<VAProfile>>(
                                            profile_description.profile)));
            continue;
          }
          decoder_description.set_profile(codec_profile);

          if (profile_description.min_width.has_value() &&
              profile_description.min_height.has_value()) {
            decoder_description.set_min_image_size(
                {profile_description.min_width.value(), profile_description.min_height.value()});
          }

          if (profile_description.max_width.has_value() &&
              profile_description.max_height.has_value()) {
            decoder_description.set_max_image_size(
                {profile_description.max_width.value(), profile_description.max_height.value()});
          }

          // VA-API currently does not support encrypted inputs.
          decoder_description.set_allow_encryption(false);
          decoder_description.set_require_encryption(false);

          decoder_descriptions.push_back(std::move(decoder_description));
        }

        // Ensure there is at least one supported decoder profile before adding the codec_profile.
        // It really doesn't make much sense to have a |DetailedCodecDescription| with no supported
        // profiles. If this is the case, then just return without adding the it to the list of
        // codec descriptions.
        if (decoder_descriptions.empty()) {
          return;
        }

        fuchsia::mediacodec::ProfileDescriptions decoder_profile_descriptions;
        decoder_profile_descriptions.set_decoder_profile_descriptions(
            std::move(decoder_descriptions));
        codec_description.set_profile_descriptions(std::move(decoder_profile_descriptions));

        codec_descriptions.push_back(std::move(codec_description));
      };

  add_decoder_profiles("video/h264", H264DecoderDescriptions());
  add_decoder_profiles("video/vp9", VP9DecoderDescriptions());

  if (SupportsJPEGDecoder()) {
    fuchsia::mediacodec::DetailedCodecDescription jpeg_description;
    jpeg_description.set_codec_type(fuchsia::mediacodec::CodecType::DECODER);
    jpeg_description.set_mime_type("video/x-motion-jpeg");
    jpeg_description.set_is_hw(true);

    fuchsia::mediacodec::DecoderProfileDescription decoder_description;
    decoder_description.set_profile(::fuchsia::media::CodecProfile::MJPEG_BASELINE);
    decoder_description.set_min_image_size({1, 1});
    // TBV whether we can successfully decode a max-dimensions jpeg via HW.
    decoder_description.set_max_image_size({65535, 65535});

    ::std::vector<::fuchsia::mediacodec::DecoderProfileDescription> decoder_descriptions;
    decoder_descriptions.emplace_back(std::move(decoder_description));
    fuchsia::mediacodec::ProfileDescriptions descriptions;
    descriptions.set_decoder_profile_descriptions(std::move(decoder_descriptions));
    jpeg_description.set_profile_descriptions(std::move(descriptions));
    codec_descriptions.emplace_back(std::move(jpeg_description));
  }

  if (SupportsH264Encoder()) {
    fuchsia::mediacodec::DetailedCodecDescription h264_description;
    h264_description.set_codec_type(fuchsia::mediacodec::CodecType::ENCODER);
    h264_description.set_mime_type("video/h264");
    h264_description.set_is_hw(true);

    fuchsia::mediacodec::EncoderProfileDescription encoder_description;
    encoder_description.set_profile(::fuchsia::media::CodecProfile::H264PROFILE_HIGH);

    ::std::vector<::fuchsia::mediacodec::EncoderProfileDescription> encoder_descriptions;
    encoder_descriptions.emplace_back(std::move(encoder_description));
    fuchsia::mediacodec::ProfileDescriptions descriptions;
    descriptions.set_encoder_profile_descriptions(std::move(encoder_descriptions));
    h264_description.set_profile_descriptions(std::move(descriptions));
    codec_descriptions.emplace_back(std::move(h264_description));
  }

  return codec_descriptions;
}
