// 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.

#include "src/sys/appmgr/component_controller_impl.h"

#include <fuchsia/inspect/cpp/fidl.h>
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fit/bridge.h>
#include <lib/fit/function.h>
#include <lib/inspect/service/cpp/service.h>
#include <zircon/types.h>

#include <cinttypes>
#include <utility>

#include <fbl/string_printf.h>
#include <fs/pseudo_file.h>
#include <fs/remote_dir.h>
#include <fs/service.h>
#include <trace/event.h>

#include "fbl/ref_ptr.h"
#include "lib/inspect/service/cpp/service.h"
#include "lib/vfs/cpp/service.h"
#include "src/lib/fsl/handles/object_info.h"
#include "src/lib/fxl/logging.h"
#include "src/sys/appmgr/component_container.h"
#include "src/sys/appmgr/namespace.h"

namespace component {

using fuchsia::sys::TerminationReason;

namespace {
zx::process DuplicateProcess(const zx::process& process) {
  zx::process ret;
  zx_status_t status = process.duplicate(ZX_RIGHT_SAME_RIGHTS, &ret);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to duplicate process handle: " << status;
  }
  return ret;
}

// TODO(fxb/46803): The out/diagnostics directory propagation for runners includes a retry.
// The reason of this is that flutter fills the out/ directory *after*
// serving it. Therefore we need to watch that directory to notify.
// Sadly the PseudoDir exposed in the SDK (and used by flutter) returns ZX_ERR_NOT_SUPPORTED on
// Watch. A solution using a watcher is implemented in fxr/366977 pending watch support.
const uint32_t MAX_RETRIES_OUT_DIAGNOSTICS = 30;
const uint32_t OUT_DIAGNOSTICS_RETRY_DELAY_MS = 500;

}  // namespace

ComponentRequestWrapper::ComponentRequestWrapper(
    fidl::InterfaceRequest<fuchsia::sys::ComponentController> request, int64_t default_return,
    fuchsia::sys::TerminationReason default_reason)
    : request_(std::move(request)), return_code_(default_return), reason_(default_reason) {}

ComponentRequestWrapper::~ComponentRequestWrapper() {
  if (request_) {
    FailedComponentController failed(return_code_, reason_, std::move(request_));
  }
}

ComponentRequestWrapper::ComponentRequestWrapper(ComponentRequestWrapper&& other) {
  *this = std::move(other);
}

void ComponentRequestWrapper::operator=(ComponentRequestWrapper&& other) {
  request_ = std::move(other.request_);
  return_code_ = std::move(other.return_code_);
  reason_ = std::move(other.reason_);
}

void ComponentRequestWrapper::SetReturnValues(int64_t return_code, TerminationReason reason) {
  return_code_ = return_code;
  reason_ = reason;
}

FailedComponentController::FailedComponentController(
    int64_t return_code, TerminationReason termination_reason,
    fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller)
    : binding_(this), return_code_(return_code), termination_reason_(termination_reason) {
  if (controller) {
    binding_.Bind(std::move(controller));
  }
}

FailedComponentController::~FailedComponentController() {
  // This can be false if other side of the channel dies before this object dies.
  if (binding_.is_bound()) {
    binding_.events().OnTerminated(return_code_, termination_reason_);
  }
}

void FailedComponentController::Kill() {}

void FailedComponentController::Detach() {}

ComponentControllerBase::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)
    : executor_(async_get_default_dispatcher()),
      binding_(this),
      label_(std::move(label)),
      hub_instance_id_(std::move(hub_instance_id)),
      url_(std::move(url)),
      hub_(fbl::AdoptRef(new fs::PseudoDir())),
      ns_(std::move(ns)),
      weak_ptr_factory_(this),
      diagnostics_max_retries_(diagnostics_max_retries) {
  if (request.is_valid()) {
    binding_.Bind(std::move(request));
    binding_.set_error_handler([this](zx_status_t /*status*/) { Kill(); });
  }
  if (!exported_dir) {
    return;
  }
  exported_dir_.Bind(std::move(exported_dir), async_get_default_dispatcher());

  if (client_request) {
    fdio_service_connect_at(exported_dir_.channel().get(), "svc", client_request.release());
  }

  ns_->set_component_id(hub_instance_id_);
  hub_.SetName(label_);
  hub_.AddEntry("url", url_);
  hub_.AddEntry("args", std::move(args));
  exported_dir_->Clone(fuchsia::io::OPEN_FLAG_DESCRIBE | fuchsia::io::OPEN_RIGHT_READABLE |
                           fuchsia::io::OPEN_RIGHT_WRITABLE,
                       cloned_exported_dir_.NewRequest());

  cloned_exported_dir_.events().OnOpen = [this](zx_status_t status,
                                                std::unique_ptr<fuchsia::io::NodeInfo> /*info*/) {
    if (status != ZX_OK) {
      FX_LOGS(WARNING) << "could not bind out directory for component" << label_ << "): " << status;
      return;
    }
    out_ready_ = true;
    auto output_dir = fbl::AdoptRef(new fs::RemoteDir(cloned_exported_dir_.Unbind().TakeChannel()));
    hub_.PublishOut(std::move(output_dir));
    NotifyDiagnosticsDirReady(diagnostics_max_retries_);
    TRACE_DURATION_BEGIN("appmgr", "ComponentController::OnDirectoryReady");
    SendOnDirectoryReadyEvent();
    TRACE_DURATION_END("appmgr", "ComponentController::OnDirectoryReady");
  };

  cloned_exported_dir_.set_error_handler(
      [this](zx_status_t status) { cloned_exported_dir_.Unbind(); });
}

void ComponentControllerBase::NotifyDiagnosticsDirReady(uint32_t max_retries) {
  auto promise =
      GetDiagnosticsDir()
          .and_then([self = weak_ptr_factory_.GetWeakPtr()](
                        fidl::InterfaceHandle<fuchsia::io::Directory>& dir) {
            if (self) {
              self->ns_->NotifyComponentDiagnosticsDirReady(self->url_, self->label_,
                                                            self->hub_instance_id_, std::move(dir));
            }
          })
          .or_else([self = weak_ptr_factory_.GetWeakPtr(), max_retries](zx_status_t& status) {
            if (self && status == ZX_ERR_NOT_FOUND) {
              async::PostDelayedTask(
                  self->executor_.dispatcher(),
                  [self = std::move(self), max_retries]() {
                    if (self && max_retries > 0) {
                      self->NotifyDiagnosticsDirReady(max_retries - 1);
                    }
                  },
                  zx::msec(OUT_DIAGNOSTICS_RETRY_DELAY_MS));
            }
            return fit::error(status);
          });
  executor_.schedule_task(std::move(promise));
}

fit::promise<fidl::InterfaceHandle<fuchsia::io::Directory>, zx_status_t>
ComponentControllerBase::GetDiagnosticsDir() {
  // This error would occur if the method was called when the component out/ directory wasn't ready
  // yet. This can be triggered when a listener is attached to a realm and notifies about existing
  // components. It could happen that the component exists, but its out is not ready yet. Under such
  // scenario, the listener will receive a START event for the existing component, but won't
  // receive a DIAGNOSTICS_DIR_READY event during the existing flow. The DIAGNOSTICS_READY_EVENT
  // will be triggered later once the out/ directory is ready if the component exposes a
  // diagnostics directory.
  if (!out_ready_) {
    return fit::make_result_promise<fidl::InterfaceHandle<fuchsia::io::Directory>>(
        fit::error(ZX_ERR_BAD_STATE));
  }
  fuchsia::io::NodePtr diagnostics_dir_node;
  fit::bridge<void, zx_status_t> bridge;
  diagnostics_dir_node.events().OnOpen =
      [completer = std::move(bridge.completer), label = label_](
          zx_status_t status, std::unique_ptr<fuchsia::io::NodeInfo> node_info) mutable {
        if (status != ZX_OK) {
          completer.complete_error(status);
        } else if (!node_info) {
          completer.complete_error(ZX_ERR_NOT_FOUND);
        } else if (!node_info->is_directory()) {
          completer.complete_error(ZX_ERR_NOT_DIR);
        } else {
          completer.complete_ok();
        }
      };

  const uint32_t flags = fuchsia::io::OPEN_FLAG_DESCRIBE | fuchsia::io::OPEN_RIGHT_READABLE |
                         fuchsia::io::OPEN_RIGHT_WRITABLE;
  exported_dir_->Open(flags, 0u /* mode */, "diagnostics", diagnostics_dir_node.NewRequest());
  return bridge.consumer.promise().and_then([diagnostics_dir_node =
                                                 std::move(diagnostics_dir_node)]() mutable {
    auto diagnostics_dir =
        fidl::InterfaceHandle<fuchsia::io::Directory>(diagnostics_dir_node.Unbind().TakeChannel());
    return fit::make_result_promise<fidl::InterfaceHandle<fuchsia::io::Directory>, zx_status_t>(
        fit::ok(std::move(diagnostics_dir)));
  });
}

void ComponentControllerBase::SendOnDirectoryReadyEvent() {
  // This can be false if
  // 1. Other side of the channel dies before this call happens.
  // 2. Component Controller request was not passed while creating the component.
  if (binding_.is_bound()) {
    binding_.events().OnDirectoryReady();
  }
}

void ComponentControllerBase::SendOnTerminationEvent(
    int64_t return_code, fuchsia::sys::TerminationReason termination_reason) {
  // `binding_.is_bound()` can be false if
  //  1. Other side of the channel dies before this call happens.
  //  2. Component Controller request was not passed while creating the component.
  if (on_terminated_event_sent_ || !binding_.is_bound()) {
    return;
  }
  FX_VLOGS(1) << "Sending termination callback with return code: " << return_code;
  binding_.events().OnTerminated(return_code, termination_reason);
  on_terminated_event_sent_ = true;
}

ComponentControllerBase::~ComponentControllerBase() = default;

HubInfo ComponentControllerBase::HubInfo() {
  return component::HubInfo(label_, hub_instance_id_, hub_.dir());
}

void ComponentControllerBase::Detach() {
  binding_.set_error_handler([](zx_status_t /*status*/) {});
}

ComponentControllerImpl::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)
    : ComponentControllerBase(std::move(request), std::move(url), std::move(args), std::move(label),
                              std::to_string(fsl::GetKoid(process.get())), std::move(ns),
                              std::move(exported_dir), std::move(client_request)),
      container_(container),
      job_(std::move(job)),
      process_(std::move(process)),
      koid_(std::to_string(fsl::GetKoid(process_.get()))),
      wait_(this, process_.get(), ZX_TASK_TERMINATED),
      system_diagnostics_(DuplicateProcess(process_)) {
  zx_status_t status = wait_.Begin(async_get_default_dispatcher());
  FX_DCHECK(status == ZX_OK);

  hub()->SetJobId(std::to_string(fsl::GetKoid(job_.get())));
  hub()->SetProcessId(koid_);

  // Serve connections to the system_diagnostics interface.
  auto system_diagnostics = fbl::MakeRefCounted<fs::PseudoDir>();
  system_diagnostics->AddEntry(
      fuchsia::inspect::Tree::Name_,
      fbl::AdoptRef(new fs::Service(
          [handler = inspect::MakeTreeHandler(&system_diagnostics_.inspector())](zx::channel chan) {
            handler(fidl::InterfaceRequest<fuchsia::inspect::Tree>(std::move(chan)));
            return ZX_OK;
          })));

  hub()->AddEntry("system_diagnostics", system_diagnostics);

  hub()->AddIncomingServices(this->incoming_services());

  if (package_handle.is_valid()) {
    hub()->AddPackageHandle(fbl::MakeRefCounted<fs::RemoteDir>(std::move(package_handle)));
  }
}

ComponentControllerImpl::~ComponentControllerImpl() {
  // Two ways we end up here:
  // 1) OnHandleReady() destroys this object; in which case, process is dead.
  // 2) Our owner destroys this object; in which case, the process may still be
  //    alive.
  if (job_) {
    job_.kill();
    // Our owner destroyed this object before we could obtain a termination
    // reason.

    SendOnTerminationEvent(-1, TerminationReason::UNKNOWN);
  }

  // Clean up system diagnostics before deleting the backing objects.
  hub()->dir()->RemoveEntry("system_diagnostics");
}

void ComponentControllerImpl::Kill() {
  FX_VLOGS(1) << "ComponentControllerImpl::Kill() called";
  TRACE_DURATION("appmgr", "ComponentController::Kill");
  if (job_) {
    job_.kill();
    job_.reset();
  }
}

bool ComponentControllerImpl::SendReturnCodeIfTerminated() {
  // Get process info.
  zx_info_process_t process_info;
  zx_status_t result =
      process_.get_info(ZX_INFO_PROCESS, &process_info, sizeof(process_info), NULL, NULL);
  FX_DCHECK(result == ZX_OK);

  if (process_info.exited) {
    SendOnTerminationEvent(process_info.return_code, TerminationReason::EXITED);
  }

  return process_info.exited;
}

zx_status_t ComponentControllerImpl::AddSubComponentHub(const component::HubInfo& hub_info) {
  hub()->EnsureComponentDir();
  return hub()->AddComponent(hub_info);
}

zx_status_t ComponentControllerImpl::RemoveSubComponentHub(const component::HubInfo& hub_info) {
  return hub()->RemoveComponent(hub_info);
}

// Called when process terminates, regardless of if Kill() was invoked.
void ComponentControllerImpl::Handler(async_dispatcher_t* dispatcher, async::WaitBase* wait,
                                      zx_status_t status, const zx_packet_signal* signal) {
  FX_DCHECK(status == ZX_OK);
  FX_DCHECK(signal->observed == ZX_TASK_TERMINATED);
  FX_VLOGS(1) << "ComponentControllerImpl::Handler() called";
  bool terminated = SendReturnCodeIfTerminated();
  FX_DCHECK(terminated);

  process_.reset();

  container_->ExtractComponent(this);
  // The destructor of the temporary returned by ExtractComponent destroys
  // |this| at the end of the previous statement.
}

ComponentBridge::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)
    : ComponentControllerBase(std::move(request), std::move(url), std::move(args), std::move(label),
                              hub_instance_id, std::move(ns), std::move(exported_dir),
                              std::move(client_request), MAX_RETRIES_OUT_DIAGNOSTICS),
      remote_controller_(std::move(remote_controller)),
      container_(std::move(container)),
      termination_reason_(TerminationReason::UNKNOWN) {
  // Forward termination callbacks from the remote component over the bridge.
  remote_controller_.events().OnTerminated = [this](int64_t return_code,
                                                    TerminationReason termination_reason) mutable {
    // Propagate the events to the external proxy.
    if (on_terminated_event_) {
      on_terminated_event_(return_code, termination_reason);
    }

    SendOnTerminationEvent(return_code, termination_reason);
    remote_controller_.events().OnTerminated = nullptr;
    container_->ExtractComponent(this);
  };

  remote_controller_.events().OnDirectoryReady = [this] { SendOnDirectoryReadyEvent(); };

  remote_controller_.set_error_handler([this](zx_status_t status) {
    if (remote_controller_.events().OnTerminated != nullptr) {
      remote_controller_.events().OnTerminated(-1, TerminationReason::UNKNOWN);
    }
  });
  // The destructor of the temporary returned by ExtractComponent destroys
  // |this| at the end of the previous statement.

  hub()->AddIncomingServices(this->incoming_services());
}

void ComponentBridge::NotifyStopped() {
  ns()->NotifyComponentStopped(url(), label(), hub_instance_id());
}

ComponentBridge::~ComponentBridge() {
  if (remote_controller_.events().OnTerminated) {
    SendOnTerminationEvent(-1, termination_reason_);
  }
}

void ComponentBridge::SetParentJobId(const std::string& id) { hub()->SetJobId(id); }

void ComponentBridge::Kill() { remote_controller_->Kill(); }

void ComponentBridge::SetTerminationReason(TerminationReason termination_reason) {
  termination_reason_ = termination_reason;
}

}  // namespace component
