// 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.

#ifndef SRC_MEDIA_CODEC_CODECS_VAAPI_VAAPI_UTILS_H_
#define SRC_MEDIA_CODEC_CODECS_VAAPI_VAAPI_UTILS_H_

#include <fuchsia/mediacodec/cpp/fidl.h>
#include <lib/fit/function.h>
#include <lib/syslog/cpp/macros.h>

#include <optional>

#include <src/lib/fxl/macros.h>
#include <va/va.h>
#include <va/va_magma.h>

#include "geometry.h"

class VADisplayWrapper {
 public:
  static bool InitializeSingleton(uint64_t vendor_id);
  static bool InitializeSingletonForTesting();

  static bool DestroySingleton();

  static VADisplayWrapper* GetSingleton();

  VADisplay display() { return display_; }

 private:
  bool Initialize();
  bool Destroy();
  magma_device_t magma_device_{};
  VADisplay display_{};
};

class ScopedConfigID {
 public:
  explicit ScopedConfigID(VAConfigID config_id) : id_(config_id) {}
  ~ScopedConfigID() { vaDestroyConfig(VADisplayWrapper::GetSingleton()->display(), id_); }

  VAConfigID id() const { return id_; }

 private:
  VAConfigID id_{VA_INVALID_ID};
  FXL_DISALLOW_COPY_ASSIGN_AND_MOVE(ScopedConfigID);
};

class ScopedBufferID {
 public:
  explicit ScopedBufferID(VABufferID buffer_id) : id_(buffer_id) {}
  ~ScopedBufferID() {
    if (id_ != VA_INVALID_ID)
      vaDestroyBuffer(VADisplayWrapper::GetSingleton()->display(), id_);
  }
  ScopedBufferID(ScopedBufferID&& other) noexcept {
    id_ = other.id_;
    other.id_ = VA_INVALID_ID;
  }

  ScopedBufferID& operator=(ScopedBufferID&& other) noexcept {
    id_ = other.id_;
    other.id_ = VA_INVALID_ID;
    return *this;
  }

  VABufferID id() const { return id_; }

 private:
  VABufferID id_{VA_INVALID_ID};
  FXL_DISALLOW_COPY_AND_ASSIGN(ScopedBufferID);
};

// For chromium code.
using ScopedVABuffer = ScopedBufferID;

class ScopedContextID {
 public:
  explicit ScopedContextID(VAContextID buffer_id) : id_(buffer_id) {}
  ~ScopedContextID() {
    if (id_ != VA_INVALID_ID)
      vaDestroyContext(VADisplayWrapper::GetSingleton()->display(), id_);
  }
  ScopedContextID(ScopedContextID&& other) noexcept {
    id_ = other.id_;
    other.id_ = VA_INVALID_ID;
  }

  ScopedContextID& operator=(ScopedContextID&& other) noexcept {
    id_ = other.id_;
    other.id_ = VA_INVALID_ID;
    return *this;
  }

  VAContextID id() const { return id_; }

 private:
  VAContextID id_{VA_INVALID_ID};
  FXL_DISALLOW_COPY_AND_ASSIGN(ScopedContextID);
};

class ScopedSurfaceID {
 public:
  explicit ScopedSurfaceID(VASurfaceID buffer_id) : id_(buffer_id) {}
  ~ScopedSurfaceID() {
    if (id_ != VA_INVALID_SURFACE)
      vaDestroySurfaces(VADisplayWrapper::GetSingleton()->display(), &id_, 1);
  }
  ScopedSurfaceID(ScopedSurfaceID&& other) noexcept {
    id_ = other.id_;
    other.id_ = VA_INVALID_SURFACE;
  }

  ScopedSurfaceID& operator=(ScopedSurfaceID&& other) noexcept {
    id_ = other.id_;
    other.id_ = VA_INVALID_SURFACE;
    return *this;
  }

  VASurfaceID id() const { return id_; }

  VASurfaceID release() {
    auto id = id_;
    id_ = VA_INVALID_SURFACE;
    return id;
  }

 private:
  VASurfaceID id_{VA_INVALID_SURFACE};
  FXL_DISALLOW_COPY_AND_ASSIGN(ScopedSurfaceID);
};

class VASurface {
 public:
  using ReleaseCB = fit::function<void(VASurfaceID)>;

  VASurface(VASurfaceID va_surface_id, const gfx::Size& size, unsigned int format,
            ReleaseCB release_cb);

  VASurface(const VASurface&) = delete;
  VASurface& operator=(const VASurface&) = delete;

  VASurfaceID id() const { return va_surface_id_; }
  const gfx::Size& size() const { return size_; }
  unsigned int format() const { return format_; }

  ~VASurface();

 private:
  const VASurfaceID va_surface_id_;
  const gfx::Size size_;
  const unsigned int format_;
  ReleaseCB release_cb_;
};

class ScopedImageID {
 public:
  explicit ScopedImageID(VAImageID image_id) : id_(image_id) {}
  ScopedImageID() = default;

  ~ScopedImageID() { DestroyImageIfNecessary(); }
  ScopedImageID(ScopedImageID&& other) noexcept {
    id_ = other.id_;
    other.id_ = VA_INVALID_ID;
  }

  ScopedImageID& operator=(ScopedImageID&& other) noexcept {
    DestroyImageIfNecessary();

    id_ = other.id_;
    other.id_ = VA_INVALID_ID;
    return *this;
  }

  VAImageID id() const { return id_; }

  VAImageID release() {
    auto id = id_;
    id_ = VA_INVALID_ID;
    return id;
  }

 private:
  void DestroyImageIfNecessary() {
    if (id_ != VA_INVALID_ID) {
      VAStatus status = vaDestroyImage(VADisplayWrapper::GetSingleton()->display(), id_);
      if (status != VA_STATUS_SUCCESS) {
        FX_LOGS(FATAL) << "vaDestroyImage failed: " << status;
      }
    }
    id_ = VA_INVALID_ID;
  }
  VAImageID id_{VA_INVALID_ID};
  FXL_DISALLOW_COPY_AND_ASSIGN(ScopedImageID);
};

std::vector<VAProfile> GetHardwareSupportedProfiles();

struct ProfileDescription {
 public:
  VAProfile profile;
  VAEntrypoint entrypoint;
  std::optional<uint32_t> min_width;
  std::optional<uint32_t> max_width;
  std::optional<uint32_t> min_height;
  std::optional<uint32_t> max_height;
};

std::optional<ProfileDescription> GetProfileDescription(
    const VAProfile& profile, VAEntrypoint required_entrypoint,
    std::vector<VAConfigAttrib>& required_attribs);

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

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

// Copy the memory between arrays with checking the array size.
template <typename T, size_t N>
inline void SafeArrayMemcpy(T (&to)[N], const T (&from)[N]) {
  std::memcpy(to, from, sizeof(T[N]));
}

#endif  // SRC_MEDIA_CODEC_CODECS_VAAPI_VAAPI_UTILS_H_
