// 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 <dlfcn.h>
#include <filesystem>
#include <memory>

#include "flutter/impeller/golden_tests/golden_playground_test.h"

#include "flutter/impeller/aiks/picture.h"
#include "flutter/impeller/golden_tests/golden_digest.h"
#include "flutter/impeller/golden_tests/metal_screenshotter.h"
#include "impeller/typographer/backends/skia/typographer_context_skia.h"
#include "impeller/typographer/typographer_context.h"

namespace impeller {

// If you add a new playground test to the aiks unittests and you do not want it
// to also be a golden test, then add the test name here.
static const std::vector<std::string> kSkipTests = {
    "impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_Metal",
    "impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_Vulkan",
    "impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_Metal",
    "impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_"
    "Vulkan",
    "impeller_Play_AiksTest_CanRenderRadialGradient_Metal",
    "impeller_Play_AiksTest_CanRenderRadialGradient_Vulkan",
    "impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Metal",
    "impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Vulkan",
    "impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_Metal",
    "impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_Vulkan",
    "impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_Metal",
    "impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_"
    "Vulkan",
    "impeller_Play_AiksTest_TextFrameSubpixelAlignment_Metal",
    "impeller_Play_AiksTest_TextFrameSubpixelAlignment_Vulkan",
    "impeller_Play_AiksTest_ColorWheel_Metal",
    "impeller_Play_AiksTest_ColorWheel_Vulkan",
    "impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Metal",
    "impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Vulkan",
    "impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Metal",
    "impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Vulkan",
    "impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_"
    "Metal",
    "impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_"
    "Vulkan",
    "impeller_Play_AiksTest_SceneColorSource_Metal",
    "impeller_Play_AiksTest_SceneColorSource_Vulkan",
    // TextRotated is flakey and we can't seem to get it to stabilize on Skia
    // Gold.
    "impeller_Play_AiksTest_TextRotated_Metal",
    "impeller_Play_AiksTest_TextRotated_Vulkan",
};

namespace {
std::string GetTestName() {
  std::string suite_name =
      ::testing::UnitTest::GetInstance()->current_test_suite()->name();
  std::string test_name =
      ::testing::UnitTest::GetInstance()->current_test_info()->name();
  std::stringstream ss;
  ss << "impeller_" << suite_name << "_" << test_name;
  std::string result = ss.str();
  // Make sure there are no slashes in the test name.
  std::replace(result.begin(), result.end(), '/', '_');
  return result;
}

std::string GetGoldenFilename() {
  return GetTestName() + ".png";
}

bool SaveScreenshot(std::unique_ptr<testing::MetalScreenshot> screenshot) {
  if (!screenshot || !screenshot->GetBytes()) {
    return false;
  }
  std::string test_name = GetTestName();
  std::string filename = GetGoldenFilename();
  testing::GoldenDigest::Instance()->AddImage(
      test_name, filename, screenshot->GetWidth(), screenshot->GetHeight());
  return screenshot->WriteToPNG(
      testing::WorkingDirectory::Instance()->GetFilenamePath(filename));
}
}  // namespace

struct GoldenPlaygroundTest::GoldenPlaygroundTestImpl {
  GoldenPlaygroundTestImpl()
      : screenshotter(new testing::MetalScreenshotter()) {}
  std::unique_ptr<testing::MetalScreenshotter> screenshotter;
  ISize window_size = ISize{1024, 768};
};

GoldenPlaygroundTest::GoldenPlaygroundTest()
    : typographer_context_(TypographerContextSkia::Make()),
      pimpl_(new GoldenPlaygroundTest::GoldenPlaygroundTestImpl()) {}

GoldenPlaygroundTest::~GoldenPlaygroundTest() = default;

void GoldenPlaygroundTest::SetTypographerContext(
    std::shared_ptr<TypographerContext> typographer_context) {
  typographer_context_ = std::move(typographer_context);
};

void GoldenPlaygroundTest::TearDown() {
  ASSERT_FALSE(dlopen("/usr/local/lib/libMoltenVK.dylib", RTLD_NOLOAD));
}

void GoldenPlaygroundTest::SetUp() {
  std::filesystem::path testing_assets_path =
      flutter::testing::GetTestingAssetsPath();
  std::filesystem::path target_path = testing_assets_path.parent_path()
                                          .parent_path()
                                          .parent_path()
                                          .parent_path();
  std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json";
  setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1);

  if (GetBackend() != PlaygroundBackend::kMetal &&
      GetBackend() != PlaygroundBackend::kVulkan) {
    GTEST_SKIP_("GoldenPlaygroundTest doesn't support this backend type.");
    return;
  }

  std::string test_name = GetTestName();
  if (std::find(kSkipTests.begin(), kSkipTests.end(), test_name) !=
      kSkipTests.end()) {
    GTEST_SKIP_(
        "GoldenPlaygroundTest doesn't support interactive playground tests "
        "yet.");
  }

  testing::GoldenDigest::Instance()->AddDimension(
      "gpu_string", GetContext()->DescribeGpuModel());
}

PlaygroundBackend GoldenPlaygroundTest::GetBackend() const {
  return GetParam();
}

bool GoldenPlaygroundTest::OpenPlaygroundHere(Picture picture) {
  AiksContext renderer(GetContext(), typographer_context_);

  auto screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, picture,
                                                          pimpl_->window_size);
  return SaveScreenshot(std::move(screenshot));
}

bool GoldenPlaygroundTest::OpenPlaygroundHere(
    AiksPlaygroundCallback
        callback) {  // NOLINT(performance-unnecessary-value-param)
  return false;
}

std::shared_ptr<Texture> GoldenPlaygroundTest::CreateTextureForFixture(
    const char* fixture_name,
    bool enable_mipmapping) const {
  std::shared_ptr<fml::Mapping> mapping =
      flutter::testing::OpenFixtureAsMapping(fixture_name);
  auto result = Playground::CreateTextureForMapping(GetContext(), mapping,
                                                    enable_mipmapping);
  if (result) {
    result->SetLabel(fixture_name);
  }
  return result;
}

std::shared_ptr<RuntimeStage> GoldenPlaygroundTest::OpenAssetAsRuntimeStage(
    const char* asset_name) const {
  auto fixture = flutter::testing::OpenFixtureAsMapping(asset_name);
  if (!fixture || fixture->GetSize() == 0) {
    return nullptr;
  }
  auto stage = std::make_unique<RuntimeStage>(std::move(fixture));
  if (!stage->IsValid()) {
    return nullptr;
  }
  return stage;
}

std::shared_ptr<Context> GoldenPlaygroundTest::GetContext() const {
  return pimpl_->screenshotter->GetPlayground().GetContext();
}

Point GoldenPlaygroundTest::GetContentScale() const {
  return pimpl_->screenshotter->GetPlayground().GetContentScale();
}

Scalar GoldenPlaygroundTest::GetSecondsElapsed() const {
  return 0.0f;
}

ISize GoldenPlaygroundTest::GetWindowSize() const {
  return pimpl_->window_size;
}

void GoldenPlaygroundTest::GoldenPlaygroundTest::SetWindowSize(ISize size) {
  pimpl_->window_size = size;
}

}  // namespace impeller
