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

#include <cstdint>

#include "gtest/gtest.h"

#include "impeller/core/allocator.h"
#include "impeller/core/device_buffer_descriptor.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/geometry/color.h"
#include "impeller/renderer/capabilities.h"
#include "impeller/renderer/pipeline.h"
#include "impeller/renderer/pipeline_descriptor.h"

namespace impeller {
namespace testing {

class FakeAllocator : public Allocator {
 public:
  FakeAllocator() : Allocator() {}

  uint16_t MinimumBytesPerRow(PixelFormat format) const override { return 0; }
  ISize GetMaxTextureSizeSupported() const override { return ISize(); }

  std::shared_ptr<DeviceBuffer> OnCreateBuffer(
      const DeviceBufferDescriptor& desc) override {
    return nullptr;
  }
  std::shared_ptr<Texture> OnCreateTexture(
      const TextureDescriptor& desc) override {
    return nullptr;
  }
};

class FakeContext : public Context {
 public:
  FakeContext() : Context(), allocator_(std::make_shared<FakeAllocator>()) {}

  BackendType GetBackendType() const override { return BackendType::kVulkan; }
  std::string DescribeGpuModel() const override { return ""; }
  bool IsValid() const override { return false; }
  const std::shared_ptr<const Capabilities>& GetCapabilities() const override {
    return capabilities_;
  }
  std::shared_ptr<Allocator> GetResourceAllocator() const override {
    return allocator_;
  }
  std::shared_ptr<ShaderLibrary> GetShaderLibrary() const { return nullptr; }
  std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const { return nullptr; }
  std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const {
    return nullptr;
  }
  std::shared_ptr<CommandBuffer> CreateCommandBuffer() const { return nullptr; }
  void Shutdown() {}

 private:
  std::shared_ptr<Allocator> allocator_;
  std::shared_ptr<const Capabilities> capabilities_;
};

class FakePipeline : public Pipeline<PipelineDescriptor> {
 public:
  FakePipeline() : Pipeline({}, PipelineDescriptor{}) {}

  bool IsValid() const override { return false; }
};

static std::shared_ptr<FakePipeline> CreateFakePipelineCallback() {
  return std::make_shared<FakePipeline>();
}

TEST(ContentContext, CachesPipelines) {
  auto context = std::make_shared<FakeContext>();
  ContentContext content_context(context, nullptr);
  ContentContextOptions optionsA{.blend_mode = BlendMode::kSourceOver};
  ContentContextOptions optionsB{.blend_mode = BlendMode::kSource};

  auto pipelineA = content_context.GetCachedRuntimeEffectPipeline(
      "A", optionsA, CreateFakePipelineCallback);

  auto pipelineA2 = content_context.GetCachedRuntimeEffectPipeline(
      "A", optionsA, CreateFakePipelineCallback);

  auto pipelineA3 = content_context.GetCachedRuntimeEffectPipeline(
      "A", optionsB, CreateFakePipelineCallback);

  auto pipelineB = content_context.GetCachedRuntimeEffectPipeline(
      "B", optionsB, CreateFakePipelineCallback);

  ASSERT_EQ(pipelineA.get(), pipelineA2.get());
  ASSERT_NE(pipelineA.get(), pipelineA3.get());
  ASSERT_NE(pipelineB.get(), pipelineA.get());
}

TEST(ContentContext, InvalidatesAllPipelinesWithSameUniqueNameOnClear) {
  auto context = std::make_shared<FakeContext>();
  ContentContext content_context(context, nullptr);
  ContentContextOptions optionsA{.blend_mode = BlendMode::kSourceOver};
  ContentContextOptions optionsB{.blend_mode = BlendMode::kSource};

  auto pipelineA = content_context.GetCachedRuntimeEffectPipeline(
      "A", optionsA, CreateFakePipelineCallback);

  auto pipelineA2 = content_context.GetCachedRuntimeEffectPipeline(
      "A", optionsB, CreateFakePipelineCallback);

  auto pipelineB = content_context.GetCachedRuntimeEffectPipeline(
      "B", optionsB, CreateFakePipelineCallback);

  ASSERT_TRUE(pipelineA);
  ASSERT_TRUE(pipelineA2);
  ASSERT_TRUE(pipelineB);

  ASSERT_EQ(pipelineA, content_context.GetCachedRuntimeEffectPipeline(
                           "A", optionsA, CreateFakePipelineCallback));
  ASSERT_EQ(pipelineA2, content_context.GetCachedRuntimeEffectPipeline(
                            "A", optionsB, CreateFakePipelineCallback));
  ASSERT_EQ(pipelineB, content_context.GetCachedRuntimeEffectPipeline(
                           "B", optionsB, CreateFakePipelineCallback));

  content_context.ClearCachedRuntimeEffectPipeline("A");

  ASSERT_NE(pipelineA, content_context.GetCachedRuntimeEffectPipeline(
                           "A", optionsA, CreateFakePipelineCallback));
  ASSERT_NE(pipelineA2, content_context.GetCachedRuntimeEffectPipeline(
                            "A", optionsB, CreateFakePipelineCallback));
  ASSERT_EQ(pipelineB, content_context.GetCachedRuntimeEffectPipeline(
                           "B", optionsB, CreateFakePipelineCallback));

  content_context.ClearCachedRuntimeEffectPipeline("B");

  ASSERT_NE(pipelineB, content_context.GetCachedRuntimeEffectPipeline(
                           "B", optionsB, CreateFakePipelineCallback));
}

}  // namespace testing
}  // namespace impeller
