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

#pragma once

#include <condition_variable>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

#include "flutter/fml/macros.h"

namespace impeller {

//------------------------------------------------------------------------------
/// @brief      A resource that may be reclaimed by a |ResourceManagerVK|.
///
/// To create a resource, use `UniqueResourceVKT` to create a unique handle:
///
///     auto resource = UniqueResourceVKT<SomeResource>(resource_manager);
///
/// @see        |ResourceManagerVK::Reclaim|.
class ResourceVK {
 public:
  virtual ~ResourceVK() = default;
};

//------------------------------------------------------------------------------
/// @brief      A resource manager controls how resources are allocated and
///             reclaimed.
///
///             Reclaimed resources are collected in a batch on a separate
///             thread. In the future, the resource manager may allow resource
///             pooling/reuse, delaying reclamation past frame workloads, etc...
///
class ResourceManagerVK final
    : public std::enable_shared_from_this<ResourceManagerVK> {
 public:
  //----------------------------------------------------------------------------
  /// @brief      Creates a shared resource manager (a dedicated thread).
  ///
  /// Upon creation, a thread is spawned which will collect resources as they
  /// are reclaimed (passed to `Reclaim`). The thread will exit when the
  /// resource manager is destroyed.
  ///
  /// @note       Only one |ResourceManagerVK| should be created per Vulkan
  ///             context, but that contract is not enforced by this method.
  ///
  /// @return     A resource manager if one could be created.
  ///
  static std::shared_ptr<ResourceManagerVK> Create();

  //----------------------------------------------------------------------------
  /// @brief      Mark a resource as being reclaimable.
  ///
  /// The resource will be reset at some point in the future.
  ///
  /// @param[in]  resource  The resource to reclaim.
  ///
  /// @note       Despite being a public API, this method cannot be invoked
  ///             directly. Instead, use `UniqueResourceVKT` to create a unique
  ///             handle to a resource, which will call this method.
  void Reclaim(std::unique_ptr<ResourceVK> resource);

  //----------------------------------------------------------------------------
  /// @brief      Destroys the resource manager.
  ///
  /// The resource manager will stop collecting resources and will be destroyed
  /// when all references to it are dropped.
  ~ResourceManagerVK();

 private:
  using Reclaimables = std::vector<std::unique_ptr<ResourceVK>>;

  ResourceManagerVK();
  std::mutex reclaimables_mutex_;
  std::condition_variable reclaimables_cv_;
  Reclaimables reclaimables_;
  bool should_exit_ = false;
  // This should be initialized last since it references the other instance
  // variables.
  std::thread waiter_;

  //----------------------------------------------------------------------------
  /// @brief      Starts the resource manager thread.
  ///
  /// This method is called implicitly by `Create`.
  void Start();

  //----------------------------------------------------------------------------
  /// @brief      Terminates the resource manager thread.
  ///
  /// Any resources given to the resource manager post termination will be
  /// collected when the resource manager is collected.
  void Terminate();

  ResourceManagerVK(const ResourceManagerVK&) = delete;

  ResourceManagerVK& operator=(const ResourceManagerVK&) = delete;
};

//------------------------------------------------------------------------------
/// @brief      An internal type that is used to move a resource reference.
///
///             Do not use directly, use `UniqueResourceVKT` instead.
///
/// @tparam     ResourceType_  The type of the resource.
///
/// @see        |UniqueResourceVKT|.
template <class ResourceType_>
class ResourceVKT : public ResourceVK {
 public:
  using ResourceType = ResourceType_;

  /// @brief      Construct a resource from a move-constructible resource.
  ///
  /// @param[in]  resource  The resource to move.
  explicit ResourceVKT(ResourceType&& resource)
      : resource_(std::move(resource)) {}

  /// @brief      Returns a pointer to the resource.
  const ResourceType* Get() const { return &resource_; }

 private:
  // Prevents subclassing, use `UniqueResourceVKT`.
  ResourceVKT() = default;

  ResourceType resource_;

  ResourceVKT(const ResourceVKT&) = delete;

  ResourceVKT& operator=(const ResourceVKT&) = delete;
};

//------------------------------------------------------------------------------
/// @brief      A unique handle to a resource which will be reclaimed by the
///             specified resource manager.
///
/// @tparam     ResourceType_  A move-constructible resource type.
///
template <class ResourceType_>
class UniqueResourceVKT final {
 public:
  using ResourceType = ResourceType_;

  /// @brief      Construct a unique resource handle belonging to a manager.
  ///
  /// Initially the handle is empty, and can be populated by calling `Swap`.
  ///
  /// @param[in]  resource_manager  The resource manager.
  explicit UniqueResourceVKT(std::weak_ptr<ResourceManagerVK> resource_manager)
      : resource_manager_(std::move(resource_manager)) {}

  /// @brief      Construct a unique resource handle belonging to a manager.
  ///
  /// Initially the handle is populated with the specified resource, but can
  /// be replaced (reclaiming the old resource) by calling `Swap`.
  ///
  /// @param[in]  resource_manager  The resource manager.
  /// @param[in]  resource          The resource to move.
  explicit UniqueResourceVKT(std::weak_ptr<ResourceManagerVK> resource_manager,
                             ResourceType&& resource)
      : resource_manager_(std::move(resource_manager)),
        resource_(
            std::make_unique<ResourceVKT<ResourceType>>(std::move(resource))) {}

  ~UniqueResourceVKT() { Reset(); }

  /// @brief      Returns a pointer to the resource.
  const ResourceType* operator->() const {
    // If this would segfault, fail with a nicer error message.
    FML_CHECK(resource_) << "UniqueResourceVKT was reclaimed.";

    return resource_.get()->Get();
  }

  /// @brief      Reclaims the existing resource, if any, and replaces it.
  ///
  /// @param[in]  other   The (new) resource to move.
  void Swap(ResourceType&& other) {
    Reset();
    resource_ = std::make_unique<ResourceVKT<ResourceType>>(std::move(other));
  }

  /// @brief      Reclaims the existing resource, if any.
  void Reset() {
    if (!resource_) {
      return;
    }
    // If there is a manager, ask it to reclaim the resource. If there isn't a
    // manager (because the manager has been destroyed), just drop it on the
    // floor here.
    if (auto manager = resource_manager_.lock()) {
      manager->Reclaim(std::move(resource_));
    }
    resource_.reset();
  }

 private:
  std::weak_ptr<ResourceManagerVK> resource_manager_;
  std::unique_ptr<ResourceVKT<ResourceType>> resource_;

  UniqueResourceVKT(const UniqueResourceVKT&) = delete;

  UniqueResourceVKT& operator=(const UniqueResourceVKT&) = delete;
};

}  // namespace impeller
