// Copyright 2021 The Fuchsia 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 LIB_SYS_COMPONENT_CPP_TESTING_INTERNAL_LOCAL_COMPONENT_RUNNER_H_
#define LIB_SYS_COMPONENT_CPP_TESTING_INTERNAL_LOCAL_COMPONENT_RUNNER_H_

#include <fuchsia/component/runner/cpp/fidl.h>
#include <fuchsia/component/test/cpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fit/function.h>
#include <lib/sys/component/cpp/testing/realm_builder_types.h>

#include <map>
#include <memory>

namespace component_testing {
namespace internal {

class LocalComponentRunner;

class LocalComponentInstance final : public fuchsia::component::runner::ComponentController {
 public:
  // Constructed by the LocalComponentRunner when the runner receives a request
  // to start a local component. The runner may optionally pass an on_exit
  // callback. This callback is not set for `LocalComponent*` component types
  // because they must stay alive for the lifetime of the Realm.
  explicit LocalComponentInstance(
      fidl::InterfaceRequest<fuchsia::component::runner::ComponentController> controller,
      async_dispatcher_t* dispatcher,
      fit::function<void(LocalComponentInstance*, std::unique_ptr<LocalComponentHandles>)> on_start,
      fit::closure on_exit);

  LocalComponentInstance(LocalComponentInstance&& other) = delete;
  LocalComponentInstance& operator=(LocalComponentInstance&& other) = delete;

  LocalComponentInstance(const LocalComponentInstance& other) = delete;
  LocalComponentInstance& operator=(const LocalComponentInstance& other) = delete;

  // Called after constructing the |LocalComponentInstance|, to start the
  // component.
  void Start(std::unique_ptr<LocalComponentHandles> handles);

  // Saves a closure to be called if component manager calls
  // |ComponentController::Stop()|. This closure should not be set for
  // |LocalComponent|s added by raw pointer because the Realm does not control
  // the lifecycle of the |LocalComponent| and the pointer could be invalid.
  void SetOnStop(fit::closure on_stop);

  // Returns true after Start() and before Exit().
  bool IsRunning();

 private:
  // fuchsia::component::runner::ComponentController
  void Stop() override;

  // fuchsia::component::runner::ComponentController
  void Kill() override;

  // If on_exit is set, close the ComponentController and call the given on_exit
  // function.
  void Exit(zx_status_t);

  fidl::Binding<fuchsia::component::runner::ComponentController> binding_;

  // If a |LocalComponentImpl| calls `Exit()` during
  // `LocalComponentImpl::OnStart()`, the LocalComponentInstance will _not_
  // immediately call `LocalComponentInstance::Exit()`. It will save the
  // provided status, and call `LocalComponentInstance::Exit()` after the
  // component has `started_`.
  cpp17::optional<zx_status_t> pending_exit_status_;

  // Set to true at the beginning of `Start()`, and false at the completion
  // of `Start()`.
  bool starting_;

  // Set to true at the completion of `Start()`.
  bool started_;

  // Called when starting the component.
  fit::function<void(LocalComponentInstance*, std::unique_ptr<LocalComponentHandles>)> on_start_;

  // Called when the component is exiting, purposefully or as a result of a
  // ComponentController::Kill().
  fit::closure on_exit_;

  // Called when the ComponentController::Stop() method is called.
  fit::closure on_stop_;
};

using LocalComponents = std::map<std::string, LocalComponentKind>;
using LocalComponentInstances = std::map<std::string, std::unique_ptr<LocalComponentInstance>>;

class LocalComponentRunner final : fuchsia::component::runner::ComponentRunner {
 public:
  LocalComponentRunner(LocalComponents components, async_dispatcher_t* dispatcher);

  LocalComponentRunner(LocalComponentRunner&& other) = delete;
  LocalComponentRunner& operator=(LocalComponentRunner&& other) = delete;

  LocalComponentRunner(const LocalComponentRunner& other) = delete;
  LocalComponentRunner& operator=(const LocalComponentRunner& other) = delete;

  fidl::InterfaceHandle<fuchsia::component::runner::ComponentRunner> NewBinding();

  void Start(
      fuchsia::component::runner::ComponentStartInfo start_info,
      fidl::InterfaceRequest<fuchsia::component::runner::ComponentController> controller) override;

  class Builder;

 private:
  // Returns true if the runner has a component with the given name that is
  // ready to be started (either it has not started, or it has stopped and
  // can be started again).
  bool ContainsReadyComponent(std::string name) const;

  // The list of components that are not running but can be started.
  LocalComponents ready_components_;

  // ComponentInstance objects for components that have been started.
  LocalComponentInstances running_components_;
  fidl::Binding<fuchsia::component::runner::ComponentRunner> binding_;
  async_dispatcher_t* dispatcher_;
};

class LocalComponentRunner::Builder final {
 public:
  Builder() = default;

  Builder(LocalComponentRunner::Builder&& other) = default;
  Builder& operator=(LocalComponentRunner::Builder&& other) = default;

  Builder(const LocalComponentRunner::Builder& other) = delete;
  Builder& operator=(const LocalComponentRunner::Builder& other) = delete;

  std::unique_ptr<LocalComponentRunner> Build(async_dispatcher_t* dispatcher);

  void Register(std::string name, LocalComponentKind mock);

 private:
  bool Contains(std::string name) const;

  LocalComponents components_;
};

}  // namespace internal
}  // namespace component_testing

#endif  // LIB_SYS_COMPONENT_CPP_TESTING_INTERNAL_LOCAL_COMPONENT_RUNNER_H_
