// Copyright 2016 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 SRC_SYS_APPMGR_COMPONENT_CONTROLLER_IMPL_H_
#define SRC_SYS_APPMGR_COMPONENT_CONTROLLER_IMPL_H_

#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async/cpp/executor.h>
#include <lib/async/cpp/wait.h>
#include <lib/fit/promise.h>
#include <lib/zx/process.h>
#include <lib/zx/status.h>
#include <zircon/assert.h>
#include <zircon/types.h>

#include <vector>

#include <fs/pseudo_dir.h>

#include "lib/fidl/cpp/binding.h"
#include "src/sys/appmgr/component_container.h"
#include "src/sys/appmgr/debug_info_retriever.h"
#include "src/sys/appmgr/hub/component_hub.h"
#include "src/sys/appmgr/hub/hub_info.h"
#include "src/sys/appmgr/namespace.h"
#include "src/sys/appmgr/system_diagnostics_directory.h"

namespace component {

// ComponentRequestWrapper wraps failure behavior in the event a Component fails
// to start. It wraps the behavior of binding to an incoming interface request
// and sending error events to clients before closing the channel.
// If there is no error, the wrapped request and callback may be Extract()ed
// and bound to a concrete interface.
// TODO(fxbug.dev/3981): Solve the general problem this solves.
class ComponentRequestWrapper {
 public:
  explicit ComponentRequestWrapper(
      fidl::InterfaceRequest<fuchsia::sys::ComponentController> request,
      int64_t default_return = -1,
      fuchsia::sys::TerminationReason default_reason = fuchsia::sys::TerminationReason::UNKNOWN);
  ~ComponentRequestWrapper();
  ComponentRequestWrapper(ComponentRequestWrapper&& other);
  void operator=(ComponentRequestWrapper&& other);

  void SetReturnValues(int64_t return_code, fuchsia::sys::TerminationReason reason);

  bool Extract(fidl::InterfaceRequest<fuchsia::sys::ComponentController>* out_request) {
    if (!request_.is_valid()) {
      return false;
    }
    *out_request = std::move(request_);
    return true;
  }

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(ComponentRequestWrapper);

 private:
  fidl::InterfaceRequest<fuchsia::sys::ComponentController> request_;
  int64_t return_code_;
  fuchsia::sys::TerminationReason reason_;
};

// FailedComponentController implements the component controller interface for
// components that failed to start. This class serves the purpose of actually
// binding to a ComponentController channel and passing back a termination
// event.
class FailedComponentController final : public fuchsia::sys::ComponentController {
 public:
  FailedComponentController(int64_t return_code, fuchsia::sys::TerminationReason termination_reason,
                            fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller);
  ~FailedComponentController() override;
  void Kill() override;
  void Detach() override;

 private:
  fidl::Binding<fuchsia::sys::ComponentController> binding_;
  int64_t return_code_;
  fuchsia::sys::TerminationReason termination_reason_;
};

class ComponentControllerBase : public fuchsia::sys::ComponentController {
 public:
  ComponentControllerBase(fidl::InterfaceRequest<fuchsia::sys::ComponentController> request,
                          std::string url, std::string args, std::string label,
                          std::string hub_instance_id, fxl::RefPtr<Namespace> ns,
                          zx::channel exported_dir, zx::channel client_request,
                          uint32_t diagnostics_max_retries = 0);
  virtual ~ComponentControllerBase() override;

 public:
  HubInfo HubInfo();
  const std::string& label() const { return label_; }
  const fbl::RefPtr<fs::PseudoDir>& hub_dir() const { return hub_.dir(); }

  // The instance ID (process koid) of the component in the hub.
  const std::string& hub_instance_id() const { return hub_instance_id_; }

  // The url of this component.
  const std::string& url() const { return url_; }

  fxl::WeakPtr<Realm> realm() { return ns_->realm(); }

  // |fuchsia::sys::ComponentController| implementation:
  void Detach() override;

  // Provides a handle to the component out/diagnostics directory if one exists.
  fit::promise<fidl::InterfaceHandle<fuchsia::io::Directory>, zx_status_t> GetDiagnosticsDir();

  // Provides a handle to the component out/svc directory if one exists.
  fit::promise<fidl::InterfaceHandle<fuchsia::io::Directory>, zx_status_t> GetServiceDir();

 protected:
  ComponentHub* hub() { return &hub_; }
  fxl::RefPtr<Namespace> ns() const { return ns_; }

  // Returns the incoming services from the namespace.
  const fbl::RefPtr<ServiceProviderDirImpl>& incoming_services() const {
    ZX_DEBUG_ASSERT(ns_);
    return ns_->services();
  };

  void SendOnDirectoryReadyEvent();

  void SendOnTerminationEvent(int64_t, fuchsia::sys::TerminationReason);

 private:
  // Notifies a realm's ComponentEventListener with the out/diagnostics directory for a component.
  void NotifyDiagnosticsDirReady(uint32_t max_retries);

  // This is the implementation of |GetDiagnosticsDir| and |GetServiceDir| as the only difference is
  // the name of the directory they are requesting.
  fit::promise<fidl::InterfaceHandle<fuchsia::io::Directory>, zx_status_t> GetDir(std::string path);

  async::Executor executor_;

  fidl::Binding<fuchsia::sys::ComponentController> binding_;

  // The name of this component: e.g., my_component.cmx
  std::string label_;

  // The instance id of this component in the hub (process koid)
  std::string hub_instance_id_;

  // The url of this component: e.g., fuchsia-pkg://fuchsia.com/my_package#meta/my_component.cmx
  std::string url_;

  ComponentHub hub_;

  fxl::RefPtr<Namespace> ns_;

  fxl::WeakPtrFactory<ComponentControllerBase> weak_ptr_factory_;

  fuchsia::io::NodePtr cloned_exported_dir_;

  fuchsia::io::DirectoryPtr exported_dir_;

  // guards against sending this event two times
  bool on_terminated_event_sent_ = false;

  // whether the out directory is ready or not.
  bool out_ready_ = false;

  uint32_t diagnostics_max_retries_ = 0;

  // Current retry backoff ms for observing a diagnostics directory. This increases every failure up
  // to OUT_DIAGNOSTICS_MAXIMUM_DELAY_MS.
  uint32_t diagnostics_retry_backoff_ms_ = 0;
};

// The path to an instance of a component. Includes the realm path, component name, and the koid of
// the component's main job.
using InstancePath = std::vector<std::string>;

class ComponentControllerImpl : public ComponentControllerBase {
 public:
  ComponentControllerImpl(fidl::InterfaceRequest<fuchsia::sys::ComponentController> request,
                          ComponentContainer<ComponentControllerImpl>* container, zx::job job,
                          zx::process process, std::string url, std::string args, std::string label,
                          fxl::RefPtr<Namespace> ns, zx::channel exported_dir,
                          zx::channel client_request, zx::channel package_handle);
  ~ComponentControllerImpl() override;

  const std::string& koid() const { return process_koid_; }

  zx_status_t AddSubComponentHub(const component::HubInfo& hub_info);
  zx_status_t RemoveSubComponentHub(const component::HubInfo& hub_info);

  // |fuchsia::sys::ComponentController| implementation:
  void Kill() override;

  const zx::job& job() const { return job_; }

 private:
  void Handler(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
               const zx_packet_signal* signal);

  // Compute the path from the component tree root to this component instance, and store it.
  //
  // The path includes the names of all realms, the component name, and the koid of the component's
  // job.
  void ComputeComponentInstancePath();

  bool SendReturnCodeIfTerminated();

  ComponentContainer<ComponentControllerImpl>* container_;
  zx::job job_;
  zx::process process_;
  const std::string process_koid_;
  const std::string job_koid_;

  async::WaitMethod<ComponentControllerImpl, &ComponentControllerImpl::Handler> wait_;

  SystemDiagnosticsDirectory system_diagnostics_;

  InstancePath instance_path_;

  FXL_DISALLOW_COPY_AND_ASSIGN(ComponentControllerImpl);
};

// This class acts as a bridge between the components created by ComponentRunner
// and |request|.
class ComponentBridge : public ComponentControllerBase {
 public:
  ComponentBridge(fidl::InterfaceRequest<fuchsia::sys::ComponentController> request,
                  fuchsia::sys::ComponentControllerPtr remote_controller,
                  ComponentContainer<ComponentBridge>* container, std::string url, std::string args,
                  std::string label, std::string hub_instance_id, fxl::RefPtr<Namespace> ns,
                  zx::channel exported_dir, zx::channel client_request,
                  std::optional<zx::channel> package_handle);

  ~ComponentBridge() override;

  void SetParentJobId(const std::string& id);

  // Set the termination reason for this bridge.
  // This should be used when a runner itself terminates and needs to report
  // back a failure over the bridge when it is closed.
  void SetTerminationReason(fuchsia::sys::TerminationReason termination_reason);

  // |fuchsia::sys::ComponentController| implementation:
  void Kill() override;

  void OnTerminated(OnTerminatedCallback callback) { on_terminated_event_ = std::move(callback); }

  void NotifyStopped();

 private:
  fuchsia::sys::ComponentControllerPtr remote_controller_;
  ComponentContainer<ComponentBridge>* container_;
  fuchsia::sys::TerminationReason termination_reason_;
  OnTerminatedCallback on_terminated_event_;

  FXL_DISALLOW_COPY_AND_ASSIGN(ComponentBridge);
};

}  // namespace component

#endif  // SRC_SYS_APPMGR_COMPONENT_CONTROLLER_IMPL_H_
