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

#include "compute_pipeline_descriptor.h"
#include "flutter/fml/macros.h"
#include "impeller/renderer/compute_pipeline_builder.h"
#include "impeller/renderer/compute_pipeline_descriptor.h"
#include "impeller/renderer/context.h"
#include "impeller/renderer/pipeline_builder.h"
#include "impeller/renderer/pipeline_descriptor.h"

namespace impeller {

class PipelineLibrary;
template <typename PipelineDescriptor_>
class Pipeline;

template <typename T>
struct PipelineFuture {
  std::optional<T> descriptor;
  std::shared_future<std::shared_ptr<Pipeline<T>>> future;

  const std::shared_ptr<Pipeline<T>> Get() const { return future.get(); }

  bool IsValid() const { return future.valid(); }
};

//------------------------------------------------------------------------------
/// @brief      Describes the fixed function and programmable aspects of
///             rendering and compute operations performed by commands submitted
///             to the GPU via a command buffer.
///
///             A pipeline handle must be allocated upfront and kept alive for
///             as long as possible. Do not create a pipeline object within a
///             frame workload.
///
///             This pipeline object is almost never used directly as it is
///             untyped. Use reflected shader information generated by the
///             Impeller offline shader compiler to generate a typed pipeline
///             object.
///
template <typename T>
class Pipeline {
 public:
  virtual ~Pipeline();

  virtual bool IsValid() const = 0;

  //----------------------------------------------------------------------------
  /// @brief      Get the descriptor that was responsible for creating this
  ///             pipeline. It may be copied and modified to create a pipeline
  ///             variant.
  ///
  /// @return     The descriptor.
  ///
  const T& GetDescriptor() const;

  PipelineFuture<T> CreateVariant(
      std::function<void(T& desc)> descriptor_callback) const;

 protected:
  Pipeline(std::weak_ptr<PipelineLibrary> library, T desc);

 private:
  const std::weak_ptr<PipelineLibrary> library_;
  const T desc_;

  Pipeline(const Pipeline&) = delete;

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

extern template class Pipeline<PipelineDescriptor>;
extern template class Pipeline<ComputePipelineDescriptor>;

PipelineFuture<PipelineDescriptor> CreatePipelineFuture(
    const Context& context,
    std::optional<PipelineDescriptor> desc);

PipelineFuture<ComputePipelineDescriptor> CreatePipelineFuture(
    const Context& context,
    std::optional<ComputePipelineDescriptor> desc);

template <class VertexShader_, class FragmentShader_>
class RenderPipelineT {
 public:
  using VertexShader = VertexShader_;
  using FragmentShader = FragmentShader_;
  using Builder = PipelineBuilder<VertexShader, FragmentShader>;

  explicit RenderPipelineT(const Context& context)
      : RenderPipelineT(CreatePipelineFuture(
            context,
            Builder::MakeDefaultPipelineDescriptor(context))) {}

  explicit RenderPipelineT(const Context& context,
                           std::optional<PipelineDescriptor> desc)
      : RenderPipelineT(CreatePipelineFuture(context, desc)) {}

  explicit RenderPipelineT(PipelineFuture<PipelineDescriptor> future)
      : pipeline_future_(std::move(future)) {}

  std::shared_ptr<Pipeline<PipelineDescriptor>> WaitAndGet() {
    if (did_wait_) {
      return pipeline_;
    }
    did_wait_ = true;
    if (pipeline_future_.IsValid()) {
      pipeline_ = pipeline_future_.Get();
    }
    return pipeline_;
  }

  std::optional<PipelineDescriptor> GetDescriptor() const {
    return pipeline_future_.descriptor;
  }

 private:
  PipelineFuture<PipelineDescriptor> pipeline_future_;
  std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline_;
  bool did_wait_ = false;

  RenderPipelineT(const RenderPipelineT&) = delete;

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

template <class ComputeShader_>
class ComputePipelineT {
 public:
  using ComputeShader = ComputeShader_;
  using Builder = ComputePipelineBuilder<ComputeShader>;

  explicit ComputePipelineT(const Context& context)
      : ComputePipelineT(CreatePipelineFuture(
            context,
            Builder::MakeDefaultPipelineDescriptor(context))) {}

  explicit ComputePipelineT(
      const Context& context,
      std::optional<ComputePipelineDescriptor> compute_desc)
      : ComputePipelineT(CreatePipelineFuture(context, compute_desc)) {}

  explicit ComputePipelineT(PipelineFuture<ComputePipelineDescriptor> future)
      : pipeline_future_(std::move(future)) {}

  std::shared_ptr<Pipeline<ComputePipelineDescriptor>> WaitAndGet() {
    if (did_wait_) {
      return pipeline_;
    }
    did_wait_ = true;
    if (pipeline_future_.IsValid()) {
      pipeline_ = pipeline_future_.Get();
    }
    return pipeline_;
  }

 private:
  PipelineFuture<ComputePipelineDescriptor> pipeline_future_;
  std::shared_ptr<Pipeline<ComputePipelineDescriptor>> pipeline_;
  bool did_wait_ = false;

  ComputePipelineT(const ComputePipelineT&) = delete;

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

}  // namespace impeller
