// Copyright 2019 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_CPP_TESTING_COMPONENT_INTERCEPTOR_H_
#define LIB_SYS_CPP_TESTING_COMPONENT_INTERCEPTOR_H_

#include <fuchsia/sys/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/testing/enclosing_environment.h>

#include <mutex>
#include <string>

namespace sys::testing {

using fuchsia::sys::TerminationReason;

// A Wrapper class which implements a basic version of
// |fuchsia::sys::ComponentController| and gives owner control over lifetime of
// this component.
class InterceptedComponent : public fuchsia::sys::ComponentController {
 public:
  // Called when this component is killed.
  using OnKill = fit::function<void()>;

  InterceptedComponent(fidl::InterfaceRequest<fuchsia::sys::ComponentController> request,
                       async_dispatcher_t* dispatcher = nullptr);

  // resets |on_kill_| to nullptr and calls |Kill()|.
  ~InterceptedComponent() override;

  void Exit(int64_t exit_code, TerminationReason reason = TerminationReason::EXITED);

  void set_on_kill(OnKill on_kill) { on_kill_ = std::move(on_kill); }

 private:
  // |ComponentController|.
  void Detach() override;

  // |ComponentController|.
  //
  // Calls |on_kill_| and call Terminated event on component before clearing the
  // bindings
  void Kill() override;

 private:
  void KillImpl();

  fidl::Binding<fuchsia::sys::ComponentController> binding_;
  TerminationReason termination_reason_;
  int64_t exit_code_;
  OnKill on_kill_;
};

// ComponentInterceptor is a utility that helps users construct an
// EnvironmentService (to be used alongside EnclosingEnvironment) that is able
// to intercept and mock components launched under the EnclosingEnvironment.
//
// This class is thread-safe. Underlying FIDL communication is processed on the
// async dispatcher supplied to this class.
class ComponentInterceptor : fuchsia::sys::Loader, fuchsia::sys::Runner {
 public:
  using ComponentLaunchHandler =
      fit::function<void(fuchsia::sys::StartupInfo, std::unique_ptr<InterceptedComponent>)>;

  ComponentInterceptor(fuchsia::sys::LoaderPtr fallback_loader,
                       async_dispatcher_t* dispatcher = nullptr);

  virtual ~ComponentInterceptor() override;

  // Constructs a fallback loader from the given |env|.
  static ComponentInterceptor CreateWithEnvironmentLoader(const fuchsia::sys::EnvironmentPtr& env,
                                                          async_dispatcher_t* dispatcher = nullptr);

  // Creates an |EnvironmentServices| which contains custom Loader and
  // Runner services which intercept component launch URLs configured using
  // |InterceptURL|. Calls to |InterceptURL| are effective regardless of if
  // they're called before or after calls to this method.
  //
  // Restrictions:
  //  * Users must not override the fuchsia::sys::Loader and
  //    fuchsia::sys::Runner services.
  //  * An instance of |ComponentInterceptor| must outlive instances of
  //    vended |EnvironmentServices|
  std::unique_ptr<EnvironmentServices> MakeEnvironmentServices(
      const fuchsia::sys::EnvironmentPtr& env);

  // Intercepts |component_url| from being launched under this environment, and
  // calls the supplied |handler| to handle the runtime of this component.
  //
  // |extra_cmx_contents| contains additional component manifest contents
  // supplied for this component.
  //   * If |extra_cmx_contents| is empty a default one is used:
  //      * {"program": {"binary": ""}}
  //   * The "runner" is always overwritten.
  //
  // Returns |false| if |extra_cmx_contents| contains invalid JSON.
  [[nodiscard]] bool InterceptURL(std::string component_url, std::string extra_cmx_contents,
                                  ComponentLaunchHandler handler);

 private:
  // Returns a faked fuchsia.sys.Package with a custom runner which forwards
  // the StartComponent request to environment's fuchsia::sys::Runner
  // service hosted by this object instance.
  //
  // |fuchsia::sys::Loader|
  void LoadUrl(std::string url, LoadUrlCallback response) override;

  // We arrive here if our fuchsia::sys::Loader sends a component launch to
  // the test harness runner component, which forwards it to here.
  //
  // |fuchsia::sys::Runner|
  void StartComponent(
      fuchsia::sys::Package package, fuchsia::sys::StartupInfo startup_info,
      fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) override;

  // Ensures that calls to intercepting URLs remains thread-safe.
  std::mutex intercept_urls_mu_;

  struct ComponentLoadInfo {
    ComponentLaunchHandler handler;
    // Fake component package directory where we host our fake manifest.
    std::unique_ptr<vfs::PseudoDir> pkg_dir;
  };
  std::map<std::string, ComponentLoadInfo> intercepted_component_load_info_
      __TA_GUARDED(intercept_urls_mu_);

  fuchsia::sys::LoaderPtr fallback_loader_;

  std::shared_ptr<vfs::Service> loader_svc_;
  fidl::BindingSet<fuchsia::sys::Loader> loader_bindings_;
  fidl::BindingSet<fuchsia::sys::Runner> runner_bindings_;

  async_dispatcher_t* dispatcher_;

  std::unique_ptr<EnclosingEnvironment> env_;
};

}  // namespace sys::testing

#endif  // LIB_SYS_CPP_TESTING_COMPONENT_INTERCEPTOR_H_
