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

#include "flutter/assets/directory_asset_bundle.h"
#include "flutter/flow/layers/container_layer.h"
#include "flutter/flow/layers/layer.h"
#include "flutter/flow/layers/physical_shape_layer.h"
#include "flutter/flow/layers/picture_layer.h"
#include "flutter/fml/command_line.h"
#include "flutter/fml/file.h"
#include "flutter/fml/log_settings.h"
#include "flutter/fml/unique_fd.h"
#include "flutter/shell/common/persistent_cache.h"
#include "flutter/shell/common/serialization_callbacks.h"
#include "flutter/shell/common/shell_test.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/version/version.h"
#include "flutter/testing/testing.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkSerialProcs.h"

namespace flutter {
namespace testing {

#if defined(OS_FUCHSIA)

static void WaitForIO(Shell* shell) {
  std::promise<bool> io_task_finished;
  shell->GetTaskRunners().GetIOTaskRunner()->PostTask(
      [&io_task_finished]() { io_task_finished.set_value(true); });
  io_task_finished.get_future().wait();
}

class SkpWarmupTest : public ShellTest {
 public:
  SkpWarmupTest() {}

  void TestWarmup(const SkISize& draw_size, const LayerTreeBuilder& builder) {
    // Create a temp dir to store the persistent cache
    fml::ScopedTemporaryDirectory dir;
    PersistentCache::SetCacheDirectoryPath(dir.path());
    PersistentCache::ResetCacheForProcess();

    auto settings = CreateSettingsForFixture();
    settings.cache_sksl = true;
    settings.dump_skp_on_shader_compilation = true;

    fml::AutoResetWaitableEvent firstFrameLatch;
    settings.frame_rasterized_callback =
        [&firstFrameLatch](const FrameTiming& t) { firstFrameLatch.Signal(); };

    auto config = RunConfiguration::InferFromSettings(settings);
    config.SetEntrypoint("emptyMain");
    std::unique_ptr<Shell> shell = CreateShell(settings);
    PlatformViewNotifyCreated(shell.get());
    RunEngine(shell.get(), std::move(config));

    // Initially, we should have no SkSL cache
    auto cache = PersistentCache::GetCacheForProcess()->LoadSkSLs();
    ASSERT_EQ(cache.size(), 0u);

    PumpOneFrame(shell.get(), draw_size.width(), draw_size.height(), builder);
    firstFrameLatch.Wait();
    WaitForIO(shell.get());

    // Count the number of shaders this builder generated. We use this as a
    // proxy for whether new shaders were generated, since skia will dump an skp
    // any time a new shader is compiled.
    int skp_count = 0;
    fml::FileVisitor skp_count_visitor = [&skp_count](
                                             const fml::UniqueFD& directory,
                                             const std::string& filename) {
      if (filename.size() >= 4 &&
          filename.substr(filename.size() - 4, 4) == ".skp") {
        skp_count += 1;
      }
      return true;
    };
    fml::VisitFilesRecursively(dir.fd(), skp_count_visitor);
    int first_skp_count = skp_count;
    skp_count = 0;
    ASSERT_GT(first_skp_count, 0);

    // Deserialize all skps into memory
    std::vector<sk_sp<SkPicture>> pictures;
    fml::FileVisitor skp_deserialize_visitor =
        [&pictures](const fml::UniqueFD& directory,
                    const std::string& filename) {
          if (filename.size() >= 4 &&
              filename.substr(filename.size() - 4, 4) == ".skp") {
            auto fd = fml::OpenFileReadOnly(directory, filename.c_str());
            if (fd.get() < 0) {
              FML_LOG(ERROR) << "Failed to open " << filename;
              return true;
            }
            // Deserialize
            sk_sp<SkData> data = SkData::MakeFromFD(fd.get());
            std::unique_ptr<SkMemoryStream> stream = SkMemoryStream::Make(data);

            SkDeserialProcs procs = {0};
            procs.fImageProc = DeserializeImageWithoutData;
            sk_sp<SkPicture> picture =
                SkPicture::MakeFromStream(stream.get(), &procs);
            pictures.push_back(std::move(picture));
            fd.reset();
          }
          return true;
        };
    fml::VisitFilesRecursively(dir.fd(), skp_deserialize_visitor);
    ASSERT_GT(pictures.size(), 0ul);

    // Reinitialize shell with clean cache and verify that drawing again dumps
    // the same number of shaders
    fml::RemoveFilesInDirectory(dir.fd());
    PersistentCache::ResetCacheForProcess();
    DestroyShell(std::move(shell));
    auto config2 = RunConfiguration::InferFromSettings(settings);
    config2.SetEntrypoint("emptyMain");
    shell = CreateShell(settings);
    PlatformViewNotifyCreated(shell.get());
    RunEngine(shell.get(), std::move(config2));
    firstFrameLatch.Reset();
    PumpOneFrame(shell.get(), draw_size.width(), draw_size.height(), builder);
    firstFrameLatch.Wait();
    WaitForIO(shell.get());

    // Verify same number of shaders dumped
    fml::VisitFilesRecursively(dir.fd(), skp_count_visitor);
    int second_skp_count = skp_count;
    skp_count = 0;
    ASSERT_EQ(second_skp_count, first_skp_count);

    // Reinitialize shell and draw deserialized skps to warm up shaders
    fml::RemoveFilesInDirectory(dir.fd());
    PersistentCache::ResetCacheForProcess();
    DestroyShell(std::move(shell));
    auto config3 = RunConfiguration::InferFromSettings(settings);
    config3.SetEntrypoint("emptyMain");
    shell = CreateShell(settings);
    PlatformViewNotifyCreated(shell.get());
    RunEngine(shell.get(), std::move(config3));
    firstFrameLatch.Reset();

    for (auto& picture : pictures) {
      fml::RefPtr<SkiaUnrefQueue> queue = fml::MakeRefCounted<SkiaUnrefQueue>(
          this->GetCurrentTaskRunner(), fml::TimeDelta::FromSeconds(0));
      LayerTreeBuilder picture_builder =
          [picture, queue](std::shared_ptr<ContainerLayer> root) {
            auto picture_layer = std::make_shared<PictureLayer>(
                SkPoint::Make(0, 0), SkiaGPUObject<SkPicture>(picture, queue),
                /* is_complex */ false,
                /* will_change */ false);
            root->Add(picture_layer);
          };
      PumpOneFrame(shell.get(), picture->cullRect().width(),
                   picture->cullRect().height(), picture_builder);
    }
    firstFrameLatch.Wait();
    WaitForIO(shell.get());

    // Verify same number of shaders dumped
    fml::VisitFilesRecursively(dir.fd(), skp_count_visitor);
    int third_skp_count = skp_count;
    skp_count = 0;
    ASSERT_EQ(third_skp_count, first_skp_count);

    // Remove files generated
    fml::RemoveFilesInDirectory(dir.fd());

    // Draw orignal material again
    firstFrameLatch.Reset();
    PumpOneFrame(shell.get(), draw_size.width(), draw_size.height(), builder);

    firstFrameLatch.Wait();
    WaitForIO(shell.get());

    // Verify no new shaders dumped
    fml::VisitFilesRecursively(dir.fd(), skp_count_visitor);
    int fourth_skp_count = skp_count;
    skp_count = 0;
    ASSERT_EQ(fourth_skp_count, 0);

    // Clean Up
    fml::RemoveFilesInDirectory(dir.fd());
  }
};

TEST_F(SkpWarmupTest, Basic) {
  SkISize draw_size = SkISize::Make(100, 100);
  // Draw something to trigger shader compilations.
  LayerTreeBuilder builder =
      [&draw_size](std::shared_ptr<ContainerLayer> root) {
        SkPath path;
        path.addCircle(draw_size.width() / 2, draw_size.height() / 2, 20);
        auto physical_shape_layer = std::make_shared<PhysicalShapeLayer>(
            SK_ColorRED, SK_ColorBLUE, 1.0f, path, Clip::antiAlias);
        root->Add(physical_shape_layer);
      };
  TestWarmup(draw_size, builder);
}

TEST_F(SkpWarmupTest, Image) {
  SkISize draw_size = SkISize::Make(100, 100);
  // We reuse this builder to draw the same content sever times in this test
  LayerTreeBuilder builder = [&draw_size,
                              this](std::shared_ptr<ContainerLayer> root) {
    SkPictureRecorder recorder;
    auto canvas =
        recorder.beginRecording(draw_size.width(), draw_size.height());

    // include an image so we can test that the warmup works even with image
    // data excluded from the skp
    auto image_size =
        SkISize::Make(draw_size.width() / 2, draw_size.height() / 2);
    auto color_space = SkColorSpace::MakeSRGB();
    auto info =
        SkImageInfo::Make(image_size, SkColorType::kRGBA_8888_SkColorType,
                          SkAlphaType::kPremul_SkAlphaType, color_space);
    sk_sp<SkData> image_data =
        SkData::MakeUninitialized(image_size.width() * image_size.height() * 4);
    memset(image_data->writable_data(), 0x0f, image_data->size());
    sk_sp<SkImage> image =
        SkImage::MakeRasterData(info, image_data, image_size.width() * 4);

    canvas->drawImage(image, image_size.width(), image_size.height());

    auto picture = recorder.finishRecordingAsPicture();

    fml::RefPtr<SkiaUnrefQueue> queue = fml::MakeRefCounted<SkiaUnrefQueue>(
        this->GetCurrentTaskRunner(), fml::TimeDelta::FromSeconds(0));
    auto picture_layer = std::make_shared<PictureLayer>(
        SkPoint::Make(0, 0), SkiaGPUObject<SkPicture>(picture, queue),
        /* is_complex */ false,
        /* will_change */ false);
    root->Add(picture_layer);
  };

  TestWarmup(draw_size, builder);
}

#endif

}  // namespace testing
}  // namespace flutter
