// 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_FUCHSIA_TESTS_MOCK_INJECTOR_REGISTRY_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_TESTS_MOCK_INJECTOR_REGISTRY_H_

#include <fuchsia/ui/pointerinjector/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>

#include <unordered_map>

namespace flutter_runner::testing {

// A test stub to act as the protocol server. A test can control what is sent
// back by this server implementation, via the ScheduleCallback call.
class MockInjectorRegistry : public fuchsia::ui::pointerinjector::Registry,
                             public fuchsia::ui::pointerinjector::Device {
 public:
  explicit MockInjectorRegistry(
      fidl::InterfaceRequest<fuchsia::ui::pointerinjector::Registry> registry)
      : registry_(this, std::move(registry)) {}

  // |fuchsia.ui.pointerinjector.Registry.Register|.
  void Register(
      fuchsia::ui::pointerinjector::Config config,
      fidl::InterfaceRequest<fuchsia::ui::pointerinjector::Device> injector,
      RegisterCallback callback) override {
    num_register_calls_++;
    const uint32_t id = next_id_++;

    auto [it, success] = bindings_.try_emplace(id, this, std::move(injector));

    it->second.set_error_handler(
        [this, id](zx_status_t status) { bindings_.erase(id); });

    config_ = std::move(config);

    callback();
  }

  // |fuchsia.ui.pointerinjector.Device.Inject|.
  void Inject(std::vector<fuchsia::ui::pointerinjector::Event> events,
              InjectCallback callback) override {
    num_events_received_ += events.size();

    for (auto& event : events) {
      events_.push_back(std::move(event));
    }

    callback();
  }

  // Returns the |fuchsia::ui::pointerinjector::Config| received in the last
  // |Register(...)| call.
  const fuchsia::ui::pointerinjector::Config& config() const { return config_; }

  // Returns all the |fuchsia::ui::pointerinjector::Event|s received from the
  // |Inject(...)| calls.
  const std::vector<fuchsia::ui::pointerinjector::Event>& events() const {
    return events_;
  }

  uint32_t num_register_calls() { return num_register_calls_; }

  size_t num_registered() { return bindings_.size(); }

  uint32_t num_events_received() const { return num_events_received_; }

 private:
  uint32_t next_id_ = 0;

  uint32_t num_events_received_ = 0;

  uint32_t num_register_calls_ = 0;

  fuchsia::ui::pointerinjector::Config config_;

  std::vector<fuchsia::ui::pointerinjector::Event> events_;

  std::unordered_map<uint32_t,
                     fidl::Binding<fuchsia::ui::pointerinjector::Device>>
      bindings_;

  fidl::Binding<fuchsia::ui::pointerinjector::Registry> registry_;

  FML_DISALLOW_COPY_AND_ASSIGN(MockInjectorRegistry);
};
}  // namespace flutter_runner::testing

#endif  // FLUTTER_SHELL_PLATFORM_FUCHSIA_TESTS_MOCK_INJECTOR_REGISTRY_H_
