// 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 "gtest/gtest.h"

#include <sstream>

#include "flutter/fml/platform/darwin/scoped_nsautorelease_pool.h"
#include "impeller/aiks/aiks_context.h"
#include "impeller/aiks/canvas.h"
#include "impeller/entity/contents/conical_gradient_contents.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/golden_tests/golden_digest.h"
#include "impeller/golden_tests/metal_screenshot.h"
#include "impeller/golden_tests/metal_screenshotter.h"
#include "impeller/golden_tests/working_directory.h"

namespace impeller {
namespace testing {

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;
  return ss.str();
}

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

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

}  // namespace

class GoldenTests : public ::testing::Test {
 public:
  GoldenTests()
      : screenshotter_(new MetalScreenshotter(/*enable_wide_gamut=*/false)) {}

  MetalScreenshotter& Screenshotter() { return *screenshotter_; }

  void SetUp() override {
    testing::GoldenDigest::Instance()->AddDimension(
        "gpu_string",
        Screenshotter().GetPlayground().GetContext()->DescribeGpuModel());
  }

 private:
  // This must be placed before any other members that may use the
  // autorelease pool.
  fml::ScopedNSAutoreleasePool autorelease_pool_;

  std::unique_ptr<MetalScreenshotter> screenshotter_;
};

TEST_F(GoldenTests, ConicalGradient) {
  Canvas canvas;
  Paint paint;

  paint.color_source = ColorSource::MakeConicalGradient(
      {125, 125}, 125, {Color(1.0, 0.0, 0.0, 1.0), Color(0.0, 0.0, 1.0, 1.0)},
      {0, 1}, {180, 180}, 0, Entity::TileMode::kClamp, {});

  paint.stroke_width = 0.0;
  paint.style = Paint::Style::kFill;
  canvas.DrawRect(Rect::MakeXYWH(10, 10, 250, 250), paint);
  Picture picture = canvas.EndRecordingAsPicture();

  auto aiks_context =
      AiksContext(Screenshotter().GetPlayground().GetContext(), nullptr);
  auto screenshot = Screenshotter().MakeScreenshot(aiks_context, picture);
  ASSERT_TRUE(SaveScreenshot(std::move(screenshot)));
}
}  // namespace testing
}  // namespace impeller
