// 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/fpromise/promise.h>
#include <lib/zx/process.h>
#include <lib/zx/result.h>
#include <zircon/assert.h>
#include <zircon/types.h>

#include <vector>

#include "lib/fidl/cpp/binding.h"
#include "src/lib/storage/vfs/cpp/pseudo_dir.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,
                          fidl::InterfaceHandle<fuchsia::io::Directory> exported_dir,
                          fidl::InterfaceRequest<fuchsia::io::Directory> 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.
  fpromise::promise<fidl::InterfaceHandle<fuchsia::io::Directory>, zx_status_t> GetDiagnosticsDir();

  // Provides a handle to the component out/svc directory if one exists.
  fpromise::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.
  fpromise::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,
                          fidl::InterfaceHandle<fuchsia::io::Directory> exported_dir,
                          fidl::InterfaceRequest<fuchsia::io::Directory> 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,
                  fidl::InterfaceHandle<fuchsia::io::Directory> exported_dir,
                  fidl::InterfaceRequest<fuchsia::io::Directory> 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_
