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

#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_UNITTESTS_UTIL_H_
#define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_UNITTESTS_UTIL_H_

#define FML_USED_ON_EMBEDDER

#include <future>

#include "flutter/fml/mapping.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/paths.h"
#include "flutter/shell/platform/embedder/tests/embedder_assertions.h"
#include "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
#include "flutter/shell/platform/embedder/tests/embedder_test.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flutter {
namespace testing {

sk_sp<SkSurface> CreateRenderSurface(const FlutterLayer& layer,
                                     GrDirectContext* context);

bool RasterImagesAreSame(sk_sp<SkImage> a, sk_sp<SkImage> b);

/// @brief      Prepends a prefix to the name which is unique to the test
///             context type. This is useful for tests that use
///             EmbedderTestMultiBackend and require different fixtures per
///             backend. For OpenGL, the name remains unchanged.
/// @param[in]  backend  The test context type used to determine the prepended
///                      prefix (e.g. `vk_[name]` for Vulkan).
/// @param[in]  name     The name of the fixture without any special prefixes.
std::string FixtureNameForBackend(EmbedderTestContextType backend,
                                  const std::string& name);

/// @brief      Resolves a render target type for a given backend description.
///             This is useful for tests that use EmbedderTestMultiBackend.
/// @param[in]  backend             The test context type to resolve the render
///                                 target for.
/// @param[in]  opengl_framebuffer  Ignored for all non-OpenGL backends. Flutter
///                                 supports rendering to both OpenGL textures
///                                 and framebuffers. When false, the OpenGL
///                                 texture render target type is returned.
EmbedderTestBackingStoreProducer::RenderTargetType GetRenderTargetFromBackend(
    EmbedderTestContextType backend,
    bool opengl_framebuffer);

/// @brief      Configures per-backend properties for a given backing store.
/// @param[in]  backing_store       The backing store to configure.
/// @param[in]  backend             The test context type used to decide which
///                                 backend the backing store will be used with.
/// @param[in]  opengl_framebuffer  Ignored for all non-OpenGL backends. Flutter
///                                 supports rendering to both OpenGL textures
///                                 and framebuffers. When false, the backing
///                                 store is configured to be an OpenGL texture.
void ConfigureBackingStore(FlutterBackingStore& backing_store,
                           EmbedderTestContextType backend,
                           bool opengl_framebuffer);

bool WriteImageToDisk(const fml::UniqueFD& directory,
                      const std::string& name,
                      sk_sp<SkImage> image);

bool ImageMatchesFixture(const std::string& fixture_file_name,
                         sk_sp<SkImage> scene_image);

bool ImageMatchesFixture(const std::string& fixture_file_name,
                         std::future<sk_sp<SkImage>>& scene_image);

bool SurfacePixelDataMatchesBytes(SkSurface* surface,
                                  const std::vector<uint8_t>& bytes);

bool SurfacePixelDataMatchesBytes(std::future<SkSurface*>& surface_future,
                                  const std::vector<uint8_t>& bytes);

void FilterMutationsByType(
    const FlutterPlatformViewMutation** mutations,
    size_t count,
    FlutterPlatformViewMutationType type,
    std::function<void(const FlutterPlatformViewMutation& mutation)> handler);

void FilterMutationsByType(
    const FlutterPlatformView* view,
    FlutterPlatformViewMutationType type,
    std::function<void(const FlutterPlatformViewMutation& mutation)> handler);

SkMatrix GetTotalMutationTransformationMatrix(
    const FlutterPlatformViewMutation** mutations,
    size_t count);

SkMatrix GetTotalMutationTransformationMatrix(const FlutterPlatformView* view);

//------------------------------------------------------------------------------
/// @brief      A task runner that we expect the embedder to provide but whose
///             implementation is a real FML task runner.
///
class EmbedderTestTaskRunner {
 public:
  using TaskExpiryCallback = std::function<void(FlutterTask)>;
  EmbedderTestTaskRunner(fml::RefPtr<fml::TaskRunner> real_task_runner,
                         TaskExpiryCallback on_task_expired)
      : identifier_(++sEmbedderTaskRunnerIdentifiers),
        real_task_runner_(real_task_runner),
        on_task_expired_(on_task_expired) {
    FML_CHECK(real_task_runner_);
    FML_CHECK(on_task_expired_);

    task_runner_description_.struct_size = sizeof(FlutterTaskRunnerDescription);
    task_runner_description_.user_data = this;
    task_runner_description_.runs_task_on_current_thread_callback =
        [](void* user_data) -> bool {
      return reinterpret_cast<EmbedderTestTaskRunner*>(user_data)
          ->real_task_runner_->RunsTasksOnCurrentThread();
    };
    task_runner_description_.post_task_callback = [](FlutterTask task,
                                                     uint64_t target_time_nanos,
                                                     void* user_data) -> void {
      auto thiz = reinterpret_cast<EmbedderTestTaskRunner*>(user_data);

      auto target_time = fml::TimePoint::FromEpochDelta(
          fml::TimeDelta::FromNanoseconds(target_time_nanos));
      auto on_task_expired = thiz->on_task_expired_;
      auto invoke_task = [task, on_task_expired]() { on_task_expired(task); };
      auto real_task_runner = thiz->real_task_runner_;

      real_task_runner->PostTaskForTime(invoke_task, target_time);
    };
    task_runner_description_.identifier = identifier_;
  }

  const FlutterTaskRunnerDescription& GetFlutterTaskRunnerDescription() {
    return task_runner_description_;
  }

 private:
  static std::atomic_size_t sEmbedderTaskRunnerIdentifiers;
  const size_t identifier_;
  fml::RefPtr<fml::TaskRunner> real_task_runner_;
  TaskExpiryCallback on_task_expired_;
  FlutterTaskRunnerDescription task_runner_description_ = {};

  FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTestTaskRunner);
};

}  // namespace testing
}  // namespace flutter

#endif  // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_UNITTESTS_UTIL_H_
