// 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 "flutter/common/graphics/persistent_cache.h"

#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/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"

namespace flutter {
namespace testing {

using PersistentCacheTest = ShellTest;

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();
}

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

TEST_F(PersistentCacheTest,
#if defined(WINUWP)
       // TODO(cbracken): https://github.com/flutter/flutter/issues/90481
       DISABLED_CacheSkSLWorks
#else
       CacheSkSLWorks
#endif  // defined(WINUWP)
) {

  // 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 first_frame_latch;
  settings.frame_rasterized_callback =
      [&first_frame_latch](const FrameTiming& t) {
        first_frame_latch.Signal();
      };

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

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

  // Draw something to trigger shader compilations.
  LayerTreeBuilder builder = [](std::shared_ptr<ContainerLayer> root) {
    SkPath path;
    path.addCircle(50, 50, 20);
    auto physical_shape_layer = std::make_shared<PhysicalShapeLayer>(
        SK_ColorRED, SK_ColorBLUE, 1.0f, path, Clip::antiAlias);
    root->Add(physical_shape_layer);
  };
  PumpOneFrame(shell.get(), 100, 100, builder);
  first_frame_latch.Wait();
  WaitForIO(shell.get());

  // Some skp should be dumped due to shader compilations.
  int skp_count = 0;
  fml::FileVisitor skp_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_visitor);
  ASSERT_GT(skp_count, 0);

  // SkSL cache should be generated by the last run.
  cache = PersistentCache::GetCacheForProcess()->LoadSkSLs();
  ASSERT_GT(cache.size(), 0u);

  // Run the engine again with cache_sksl = false and check that the previously
  // generated SkSL cache is used for precompile.
  PersistentCache::ResetCacheForProcess();
  settings.cache_sksl = false;
  settings.dump_skp_on_shader_compilation = true;
  auto normal_config = RunConfiguration::InferFromSettings(settings);
  normal_config.SetEntrypoint("emptyMain");
  DestroyShell(std::move(shell));
  shell = CreateShell(settings);
  PlatformViewNotifyCreated(shell.get());
  RunEngine(shell.get(), std::move(normal_config));
  first_frame_latch.Reset();
  PumpOneFrame(shell.get(), 100, 100, builder);
  first_frame_latch.Wait();
  WaitForIO(shell.get());

// Shader precompilation from SkSL is not implemented on the Skia Vulkan
// backend so don't run the second half of this test on Vulkan. This can get
// removed if SkSL precompilation is implemented in the Skia Vulkan backend.
#if !defined(SHELL_ENABLE_VULKAN)
  // To check that all shaders are precompiled, verify that no new skp is dumped
  // due to shader compilations.
  int old_skp_count = skp_count;
  skp_count = 0;
  fml::VisitFilesRecursively(dir.fd(), skp_visitor);
  ASSERT_EQ(skp_count, old_skp_count);
#endif  // !defined(SHELL_ENABLE_VULKAN)

  // Remove all files generated
  fml::RemoveFilesInDirectory(dir.fd());
  DestroyShell(std::move(shell));
}

TEST_F(PersistentCacheTest, CanPrecompileMetalShaders) {
#if !SHELL_ENABLE_METAL
  GTEST_SKIP();
#endif  //  !SHELL_ENABLE_METAL
  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 first_frame_latch;
  settings.frame_rasterized_callback =
      [&first_frame_latch](const FrameTiming& t) {
        first_frame_latch.Signal();
      };

  auto sksl_config = RunConfiguration::InferFromSettings(settings);
  sksl_config.SetEntrypoint("emptyMain");
  std::unique_ptr<Shell> shell =
      CreateShell(settings,                                          //
                  GetTaskRunnersForFixture(),                        //
                  false,                                             //
                  nullptr,                                           //
                  false,                                             //
                  ShellTestPlatformView::BackendType::kMetalBackend  //
      );
  PlatformViewNotifyCreated(shell.get());
  RunEngine(shell.get(), std::move(sksl_config));

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

  // Draw something to trigger shader compilations.
  LayerTreeBuilder builder = [](std::shared_ptr<ContainerLayer> root) {
    SkPath path;
    path.addCircle(50, 50, 20);
    auto physical_shape_layer = std::make_shared<PhysicalShapeLayer>(
        SK_ColorRED, SK_ColorBLUE, 1.0f, path, Clip::antiAlias);
    root->Add(physical_shape_layer);
  };
  PumpOneFrame(shell.get(), 100, 100, builder);
  first_frame_latch.Wait();
  WaitForRaster(shell.get());
  WaitForIO(shell.get());

  // Assert that SkSLs have been generated.
  auto filled_cache = PersistentCache::GetCacheForProcess()->LoadSkSLs();
  ASSERT_GT(filled_cache.size(), 0u);

  // Remove all files generated.
  fml::RemoveFilesInDirectory(dir.fd());
  DestroyShell(std::move(shell));
}

static void CheckTextSkData(sk_sp<SkData> data, const std::string& expected) {
  std::string data_string(reinterpret_cast<const char*>(data->bytes()),
                          data->size());
  ASSERT_EQ(data_string, expected);
}

static void ResetAssetManager() {
  PersistentCache::SetAssetManager(nullptr);
  ASSERT_EQ(PersistentCache::GetCacheForProcess()->LoadSkSLs().size(), 0u);
}

static void CheckTwoSkSLsAreLoaded() {
  auto shaders = PersistentCache::GetCacheForProcess()->LoadSkSLs();
  ASSERT_EQ(shaders.size(), 2u);
}

TEST_F(PersistentCacheTest,
#if defined(WINUWP)
       // TODO(cbracken): https://github.com/flutter/flutter/issues/90481
       DISABLED_CanLoadSkSLsFromAsset
#else
       CanLoadSkSLsFromAsset
#endif  // defined(WINUWP)
) {

  // Avoid polluting unit tests output by hiding INFO level logging.
  fml::LogSettings warning_only = {fml::LOG_WARNING};
  fml::ScopedSetLogSettings scoped_set_log_settings(warning_only);

  // The SkSL key is Base32 encoded. "IE" is the encoding of "A" and "II" is the
  // encoding of "B".
  //
  // The SkSL data is Base64 encoded. "eA==" is the encoding of "x" and "eQ=="
  // is the encoding of "y".
  const std::string kTestJson =
      "{\n"
      "  \"data\": {\n"
      "    \"IE\": \"eA==\",\n"
      "    \"II\": \"eQ==\"\n"
      "  }\n"
      "}\n";

  // Temp dir for the asset.
  fml::ScopedTemporaryDirectory asset_dir;

  auto data = std::make_unique<fml::DataMapping>(
      std::vector<uint8_t>{kTestJson.begin(), kTestJson.end()});
  fml::WriteAtomically(asset_dir.fd(), PersistentCache::kAssetFileName, *data);

  // 1st, test that RunConfiguration::InferFromSettings sets the asset manager.
  ResetAssetManager();
  auto settings = CreateSettingsForFixture();
  settings.assets_path = asset_dir.path();
  RunConfiguration::InferFromSettings(settings);
  CheckTwoSkSLsAreLoaded();

  // 2nd, test that the RunConfiguration constructor sets the asset manager.
  // (Android is directly calling that constructor without InferFromSettings.)
  ResetAssetManager();
  auto asset_manager = std::make_shared<AssetManager>();
  RunConfiguration config(nullptr, asset_manager);
  asset_manager->PushBack(std::make_unique<DirectoryAssetBundle>(
      fml::OpenDirectory(asset_dir.path().c_str(), false,
                         fml::FilePermission::kRead),
      false));
  CheckTwoSkSLsAreLoaded();

  // 3rd, test the content of the SkSLs in the asset.
  {
    auto shaders = PersistentCache::GetCacheForProcess()->LoadSkSLs();
    ASSERT_EQ(shaders.size(), 2u);

    // Make sure that the 2 shaders are sorted by their keys. Their keys should
    // be "A" and "B" (decoded from "II" and "IE").
    if (shaders[0].key->bytes()[0] == 'B') {
      std::swap(shaders[0], shaders[1]);
    }

    CheckTextSkData(shaders[0].key, "A");
    CheckTextSkData(shaders[1].key, "B");
    CheckTextSkData(shaders[0].value, "x");
    CheckTextSkData(shaders[1].value, "y");
  }

  // Cleanup.
  fml::UnlinkFile(asset_dir.fd(), PersistentCache::kAssetFileName);
}

TEST_F(PersistentCacheTest,
#if defined(WINUWP)
       // TODO(cbracken): https://github.com/flutter/flutter/issues/90481
       DISABLED_CanRemoveOldPersistentCache
#else
       CanRemoveOldPersistentCache
#endif  // defined(WINUWP)
) {

  fml::ScopedTemporaryDirectory base_dir;
  ASSERT_TRUE(base_dir.fd().is_valid());

  fml::CreateDirectory(base_dir.fd(),
                       {"flutter_engine", GetFlutterEngineVersion(), "skia"},
                       fml::FilePermission::kReadWrite);

  constexpr char kOldEngineVersion[] = "old";
  auto old_created = fml::CreateDirectory(
      base_dir.fd(), {"flutter_engine", kOldEngineVersion, "skia"},
      fml::FilePermission::kReadWrite);
  ASSERT_TRUE(old_created.is_valid());

  PersistentCache::SetCacheDirectoryPath(base_dir.path());
  PersistentCache::ResetCacheForProcess();

  auto engine_dir = fml::OpenDirectoryReadOnly(base_dir.fd(), "flutter_engine");
  auto current_dir =
      fml::OpenDirectoryReadOnly(engine_dir, GetFlutterEngineVersion());
  auto old_dir = fml::OpenDirectoryReadOnly(engine_dir, kOldEngineVersion);

  ASSERT_TRUE(engine_dir.is_valid());
  ASSERT_TRUE(current_dir.is_valid());
  ASSERT_FALSE(old_dir.is_valid());

  // Cleanup
  fml::RemoveFilesInDirectory(base_dir.fd());
}

TEST_F(PersistentCacheTest,
#if defined(WINUWP)
       // TODO(cbracken): https://github.com/flutter/flutter/issues/90481
       DISABLED_CanPurgePersistentCache
#else
       CanPurgePersistentCache
#endif  // defined(WINUWP)
) {

  fml::ScopedTemporaryDirectory base_dir;
  ASSERT_TRUE(base_dir.fd().is_valid());
  auto cache_dir = fml::CreateDirectory(
      base_dir.fd(),
      {"flutter_engine", GetFlutterEngineVersion(), "skia", GetSkiaVersion()},
      fml::FilePermission::kReadWrite);
  PersistentCache::SetCacheDirectoryPath(base_dir.path());
  PersistentCache::ResetCacheForProcess();

  // Generate a dummy persistent cache.
  fml::DataMapping test_data(std::string("test"));
  ASSERT_TRUE(fml::WriteAtomically(cache_dir, "test", test_data));
  auto file = fml::OpenFileReadOnly(cache_dir, "test");
  ASSERT_TRUE(file.is_valid());

  // Run engine with purge_persistent_cache to remove the dummy cache.
  auto settings = CreateSettingsForFixture();
  settings.purge_persistent_cache = true;
  auto config = RunConfiguration::InferFromSettings(settings);
  std::unique_ptr<Shell> shell = CreateShell(settings);
  RunEngine(shell.get(), std::move(config));

  // Verify that the dummy is purged.
  file = fml::OpenFileReadOnly(cache_dir, "test");
  ASSERT_FALSE(file.is_valid());

  // Cleanup
  fml::RemoveFilesInDirectory(base_dir.fd());
  DestroyShell(std::move(shell));
}

TEST_F(PersistentCacheTest,
#if defined(WINUWP)
       // TODO(cbracken): https://github.com/flutter/flutter/issues/90481
       DISABLED_PurgeAllowsFutureSkSLCache
#else
       PurgeAllowsFutureSkSLCache
#endif  // defined(WINUWP)
) {

  sk_sp<SkData> shader_key = SkData::MakeWithCString("key");
  sk_sp<SkData> shader_value = SkData::MakeWithCString("value");
  std::string shader_filename = PersistentCache::SkKeyToFilePath(*shader_key);

  fml::ScopedTemporaryDirectory base_dir;
  ASSERT_TRUE(base_dir.fd().is_valid());
  PersistentCache::SetCacheDirectoryPath(base_dir.path());
  PersistentCache::ResetCacheForProcess();

  // Run engine with purge_persistent_cache and cache_sksl.
  auto settings = CreateSettingsForFixture();
  settings.purge_persistent_cache = true;
  settings.cache_sksl = true;
  auto config = RunConfiguration::InferFromSettings(settings);
  std::unique_ptr<Shell> shell = CreateShell(settings);
  RunEngine(shell.get(), std::move(config));
  auto persistent_cache = PersistentCache::GetCacheForProcess();
  ASSERT_EQ(persistent_cache->LoadSkSLs().size(), 0u);

  // Store the cache and verify it's valid.
  StorePersistentCache(persistent_cache, *shader_key, *shader_value);
  std::promise<bool> io_flushed;
  shell->GetTaskRunners().GetIOTaskRunner()->PostTask(
      [&io_flushed]() { io_flushed.set_value(true); });
  io_flushed.get_future().get();  // Wait for the IO thread to flush the file.
  ASSERT_GT(persistent_cache->LoadSkSLs().size(), 0u);

  // Cleanup
  fml::RemoveFilesInDirectory(base_dir.fd());
  DestroyShell(std::move(shell));
}

}  // namespace testing
}  // namespace flutter
