// 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_TEST_COMPOSITOR_H_
#define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_TEST_COMPOSITOR_H_

#include <vector>

#include "flutter/fml/closure.h"
#include "flutter/fml/macros.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_backingstore_producer.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"

namespace flutter {
namespace testing {

class EmbedderTestCompositor {
 public:
  using PlatformViewRendererCallback =
      std::function<sk_sp<SkImage>(const FlutterLayer& layer,
                                   GrDirectContext* context)>;
  using PresentCallback =
      std::function<void(const FlutterLayer** layers, size_t layers_count)>;

  EmbedderTestCompositor(SkISize surface_size, sk_sp<GrDirectContext> context);

  virtual ~EmbedderTestCompositor();

  void SetBackingStoreProducer(
      std::unique_ptr<EmbedderTestBackingStoreProducer> backingstore_producer);

  bool CreateBackingStore(const FlutterBackingStoreConfig* config,
                          FlutterBackingStore* backing_store_out);

  bool CollectBackingStore(const FlutterBackingStore* backing_store);

  bool Present(const FlutterLayer** layers, size_t layers_count);

  void SetPlatformViewRendererCallback(
      const PlatformViewRendererCallback& callback);

  //----------------------------------------------------------------------------
  /// @brief      Allows tests to install a callback to notify them when the
  ///             entire render tree has been finalized so they can run their
  ///             assertions.
  ///
  /// @param[in]  next_present_callback  The next present callback
  ///
  void SetNextPresentCallback(const PresentCallback& next_present_callback);

  void SetPresentCallback(const PresentCallback& present_callback,
                          bool one_shot);

  using NextSceneCallback = std::function<void(sk_sp<SkImage> image)>;
  void SetNextSceneCallback(const NextSceneCallback& next_scene_callback);

  sk_sp<SkImage> GetLastComposition();

  size_t GetPendingBackingStoresCount() const;

  size_t GetBackingStoresCreatedCount() const;

  size_t GetBackingStoresCollectedCount() const;

  void AddOnCreateRenderTargetCallback(const fml::closure& callback);

  void AddOnCollectRenderTargetCallback(const fml::closure& callback);

  void AddOnPresentCallback(const fml::closure& callback);

  sk_sp<GrDirectContext> GetGrContext();

 protected:
  virtual bool UpdateOffscrenComposition(const FlutterLayer** layers,
                                         size_t layers_count) = 0;

  // TODO(gw280): encapsulate these properly for subclasses to use
  std::unique_ptr<EmbedderTestBackingStoreProducer> backingstore_producer_;
  const SkISize surface_size_;
  sk_sp<GrDirectContext> context_;

  PlatformViewRendererCallback platform_view_renderer_callback_;
  bool present_callback_is_one_shot_ = false;
  PresentCallback present_callback_;
  NextSceneCallback next_scene_callback_;
  sk_sp<SkImage> last_composition_;
  size_t backing_stores_created_ = 0;
  size_t backing_stores_collected_ = 0;
  std::vector<fml::closure> on_create_render_target_callbacks_;
  std::vector<fml::closure> on_collect_render_target_callbacks_;
  std::vector<fml::closure> on_present_callbacks_;

  FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTestCompositor);
};

}  // namespace testing
}  // namespace flutter

#endif  // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_TEST_COMPOSITOR_GL_H_
