// Copyright 2018 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 <fuchsia/boot/c/fidl.h>
#include <fuchsia/boot/llcpp/fidl.h>
#include <fuchsia/exception/llcpp/fidl.h>
#include <fuchsia/kernel/c/fidl.h>
#include <fuchsia/power/manager/llcpp/fidl.h>
#include <fuchsia/scheduler/c/fidl.h>
#include <fuchsia/sys2/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/wait.h>
#include <lib/async/dispatcher.h>
#include <lib/devmgr-integration-test/fixture.h>
#include <lib/devmgr-launcher/launch.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fidl-async/bind.h>
#include <lib/fidl-async/cpp/bind.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/service/llcpp/service.h>
#include <lib/vfs/cpp/remote_dir.h>
#include <lib/zx/exception.h>
#include <stdint.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls/exception.h>

#include <map>
#include <thread>
#include <utility>

#include <fbl/algorithm.h>
#include <fbl/ref_ptr.h>
#include <fbl/string_printf.h>
#include <mock-boot-arguments/server.h>

#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
#include "src/lib/storage/vfs/cpp/service.h"
#include "src/lib/storage/vfs/cpp/synchronous_vfs.h"
#include "src/lib/storage/vfs/cpp/vfs_types.h"

namespace {

using GetBootItemFunction = devmgr_launcher::GetBootItemFunction;

// TODO(http://fxbug.dev/33183): Replace this with a test component_manager.
class FakeRealm : public fidl::WireInterface<fuchsia_sys2::Realm> {
 public:
  void BindChild(fuchsia_sys2::wire::ChildRef child,
                 fidl::ServerEnd<fuchsia_io::Directory> exposed_dir,
                 BindChildCompleter::Sync& completer) override {
    exposed_dir_ = std::move(exposed_dir);
    completer.ReplySuccess();
  }

  void CreateChild(fuchsia_sys2::wire::CollectionRef collection, fuchsia_sys2::wire::ChildDecl decl,
                   CreateChildCompleter::Sync& completer) override {
    completer.ReplySuccess();
  }

  void DestroyChild(fuchsia_sys2::wire::ChildRef child,
                    DestroyChildCompleter::Sync& completer) override {}

  void ListChildren(fuchsia_sys2::wire::CollectionRef collection,
                    fidl::ServerEnd<fuchsia_sys2::ChildIterator> iter,
                    ListChildrenCompleter::Sync& completer) override {}

 private:
  fidl::ServerEnd<fuchsia_io::Directory> exposed_dir_;
};

class FakePowerRegistration
    : public fidl::WireInterface<fuchsia_power_manager::DriverManagerRegistration> {
 public:
  void Register(fidl::ClientEnd<fuchsia_device_manager::SystemStateTransition> transition,
                fidl::ClientEnd<fuchsia_io::Directory> dir,
                RegisterCompleter::Sync& completer) override {
    // Store these so the other side doesn't see the channels close.
    transition_ = std::move(transition);
    dir_ = std::move(dir);
    completer.ReplySuccess();
  }

 private:
  fidl::ClientEnd<fuchsia_device_manager::SystemStateTransition> transition_;
  fidl::ClientEnd<fuchsia_io::Directory> dir_;
};

zx_status_t ItemsGet(void* ctx, uint32_t type, uint32_t extra, fidl_txn_t* txn) {
  const auto& get_boot_item = *static_cast<GetBootItemFunction*>(ctx);
  zx::vmo vmo;
  uint32_t length = 0;
  if (get_boot_item) {
    zx_status_t status = get_boot_item(type, extra, &vmo, &length);
    if (status != ZX_OK) {
      return status;
    }
  }
  return fuchsia_boot_ItemsGet_reply(txn, vmo.release(), length);
}

constexpr fuchsia_boot_Items_ops kItemsOps = {
    .Get = ItemsGet,
};

zx_status_t RootJobGet(void* ctx, fidl_txn_t* txn) {
  const auto& root_job = *static_cast<zx::unowned_job*>(ctx);
  zx::job job;
  zx_status_t status = root_job->duplicate(ZX_RIGHT_SAME_RIGHTS, &job);
  if (status != ZX_OK) {
    return status;
  }
  return fuchsia_kernel_RootJobGet_reply(txn, job.release());
}

constexpr fuchsia_kernel_RootJob_ops kRootJobOps = {
    .Get = RootJobGet,
};

template <class Protocol>
void CreateFakeCppService(fbl::RefPtr<fs::PseudoDir> root, async_dispatcher_t* dispatcher,
                          std::unique_ptr<typename fidl::WireInterface<Protocol>> server) {
  auto node = fbl::MakeRefCounted<fs::Service>(
      [dispatcher, server{std::move(server)}](fidl::ServerEnd<Protocol> channel) {
        return fidl::BindSingleInFlightOnly(dispatcher, std::move(channel), server.get());
      });
  root->AddEntry(fidl::DiscoverableProtocolName<Protocol>, node);
}

void CreateFakeService(fbl::RefPtr<fs::PseudoDir> root, const char* name,
                       async_dispatcher_t* dispatcher, fidl_dispatch_t* dispatch, void* ctx,
                       const void* ops) {
  auto node =
      fbl::MakeRefCounted<fs::Service>([dispatcher, dispatch, ctx, ops](zx::channel channel) {
        return fidl_bind(dispatcher, channel.release(), dispatch, ctx, ops);
      });
  root->AddEntry(name, node);
}

void ForwardService(fbl::RefPtr<fs::PseudoDir> root, const char* name,
                    fidl::ClientEnd<fuchsia_io::Directory> svc_client) {
  root->AddEntry(name, fbl::MakeRefCounted<fs::Service>(
                           [name, svc_client = std::move(svc_client)](zx::channel request) {
                             return fdio_service_connect_at(svc_client.channel().get(), name,
                                                            request.release());
                           }));
}

fidl::ClientEnd<fuchsia_io::Directory> CloneDirectory(
    fidl::UnownedClientEnd<fuchsia_io::Directory> end) {
  return service::MaybeClone(end);
}

}  // namespace

namespace devmgr_integration_test {

// We keep this structure opaque so that we don't grow a bunch of public dependencies for the
// implementation of this loop
struct IsolatedDevmgr::SvcLoopState {
  ~SvcLoopState() {
    // We must shut down the loop before we operate on vfs and bootsvc_wait in order to prevent
    // concurrent access to them
    loop.Shutdown();
  }

  GetBootItemFunction get_boot_item;

  async::Loop loop{&kAsyncLoopConfigNoAttachToCurrentThread};
  fbl::RefPtr<fs::PseudoDir> root{fbl::MakeRefCounted<fs::PseudoDir>()};
  fs::SynchronousVfs vfs{loop.dispatcher()};
  async::Wait bootsvc_wait;
};

struct IsolatedDevmgr::ExceptionLoopState {
  ExceptionLoopState(async_dispatcher_t* dispatcher, zx::channel exception_channel)
      : dispatcher_(dispatcher),
        exception_channel_(std::move(exception_channel)),
        watcher_(this, exception_channel_.get(), ZX_CHANNEL_READABLE) {
    if (dispatcher_ == nullptr) {
      loop_.emplace(&kAsyncLoopConfigNoAttachToCurrentThread);
      dispatcher_ = loop_->dispatcher();
    }
    watcher_.Begin(dispatcher_);
  }
  ~ExceptionLoopState() {
    // We must shut down the loop before we operate on watcher_ in order to prevent
    // concurrent access to them. If dispatcher is passed in, this should be done beforehand.
    if (loop_) {
      loop_->Shutdown();
    }
  }

  void HandleException() {
    printf("Handling devmgr exception\n");
    zx_exception_info_t info;
    zx::exception exception;
    zx_status_t status = exception_channel_.read(0, &info, exception.reset_and_get_address(),
                                                 sizeof(info), 1, nullptr, nullptr);
    if (status != ZX_OK) {
      return;
    }

    // Send exceptions to the ambient fuchsia.exception.Handler.
    auto local = service::Connect<fuchsia_exception::Handler>();
    if (!local.is_ok()) {
      return;
    }
    fidl::WireSyncClient<fuchsia_exception::Handler> handler(std::move(*local));
    fuchsia_exception::wire::ExceptionInfo einfo;
    einfo.process_koid = info.pid;
    einfo.thread_koid = info.tid;
    einfo.type = static_cast<fuchsia_exception::wire::ExceptionType>(info.type);
    handler.OnException(std::move(exception), einfo);
  }

  void DevmgrException(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                       const zx_packet_signal_t* signal) {
    if (status == ZX_ERR_CANCELED) {
      return;
    }
    crashed_ = true;
    HandleException();
    if (exception_callback_) {
      exception_callback_();
    }
  }

  std::optional<async::Loop> loop_;
  async_dispatcher_t* dispatcher_ = nullptr;

  zx::channel exception_channel_;
  std::atomic<bool> crashed_ = false;
  fit::closure exception_callback_;
  async::WaitMethod<ExceptionLoopState, &ExceptionLoopState::DevmgrException> watcher_;
};

zx_status_t IsolatedDevmgr::SetupExceptionLoop(async_dispatcher_t* dispatcher,
                                               zx::channel exception_channel) {
  exception_loop_state_ =
      std::make_unique<ExceptionLoopState>(dispatcher, std::move(exception_channel));

  if (dispatcher == nullptr) {
    return exception_loop_state_->loop_->StartThread("isolated-devmgr-exceptionloop");
  } else {
    return ZX_OK;
  }
}

// Create and host a /svc directory for the devcoordinator process we're creating.
// TODO(fxbug.dev/35991): IsolatedDevmgr and devmgr_launcher should be rewritten to make use of
// Components v2/Test Framework concepts as soon as those are ready enough. For now this has to be
// manually kept in sync with devcoordinator's manifest in //src/sys/root/devcoordinator.cml
// (although it already seems to be incomplete).
zx_status_t IsolatedDevmgr::SetupSvcLoop(
    fidl::ServerEnd<fuchsia_io::Directory> bootsvc_server,
    fidl::ClientEnd<fuchsia_io::Directory> fshost_outgoing_client,
    GetBootItemFunction get_boot_item, std::map<std::string, std::string>&& boot_args) {
  svc_loop_state_ = std::make_unique<SvcLoopState>();
  svc_loop_state_->get_boot_item = std::move(get_boot_item);

  // Quit the loop when the channel is closed.
  svc_loop_state_->bootsvc_wait.set_object(bootsvc_server.channel().get());
  svc_loop_state_->bootsvc_wait.set_trigger(ZX_CHANNEL_PEER_CLOSED);
  svc_loop_state_->bootsvc_wait.set_handler([loop = &svc_loop_state_->loop](...) { loop->Quit(); });
  svc_loop_state_->bootsvc_wait.Begin(svc_loop_state_->loop.dispatcher());

  // Connect to /svc in the current namespace.
  auto svc_client = *service::OpenServiceRoot();

  // Connect to /svc in fshost's outgoing directory
  auto fshost_endpoints = fidl::CreateEndpoints<fuchsia_io::Directory>();
  if (!fshost_endpoints.is_ok()) {
    return fshost_endpoints.status_value();
  }
  auto [fshost_svc_client, fshost_svc_server] = *std::move(fshost_endpoints);

  zx_status_t status =
      fdio_open_at(fshost_outgoing_client.channel().get(), "svc",
                   ZX_FS_RIGHT_READABLE | ZX_FS_RIGHT_WRITABLE | ZX_FS_FLAG_DIRECTORY,
                   fshost_svc_server.TakeChannel().release());
  if (status != ZX_OK) {
    return status;
  }

  // Forward required services from the current namespace.
  ForwardService(svc_loop_state_->root, "fuchsia.process.Launcher", CloneDirectory(svc_client));
  ForwardService(svc_loop_state_->root, "fuchsia.logger.LogSink", CloneDirectory(svc_client));
  ForwardService(svc_loop_state_->root, "fuchsia.boot.RootResource", std::move(svc_client));
  ForwardService(svc_loop_state_->root, "fuchsia.fshost.Loader", std::move(fshost_svc_client));

  boot_args.try_emplace("virtcon.disable", "true");

  // Host fake instances of some services normally provided by bootsvc and routed to devcoordinator
  // by component_manager. The difference between these fakes and the optional services above is
  // that these 1) are fakeable (unlike fuchsia.process.Launcher) and 2) seem to be required
  // services for devcoordinator.
  auto items_dispatch = reinterpret_cast<fidl_dispatch_t*>(fuchsia_boot_Items_dispatch);
  CreateFakeService(svc_loop_state_->root, fuchsia_boot_Items_Name,
                    svc_loop_state_->loop.dispatcher(), items_dispatch,
                    &svc_loop_state_->get_boot_item, &kItemsOps);

  auto root_job_dispatch = reinterpret_cast<fidl_dispatch_t*>(fuchsia_kernel_RootJob_dispatch);
  CreateFakeService(svc_loop_state_->root, fuchsia_kernel_RootJob_Name,
                    svc_loop_state_->loop.dispatcher(), root_job_dispatch, &job_, &kRootJobOps);

  // Create fake Boot Arguments.
  CreateFakeCppService<fuchsia_boot::Arguments>(
      svc_loop_state_->root, svc_loop_state_->loop.dispatcher(),
      std::make_unique<mock_boot_arguments::Server>(std::move(boot_args)));

  // Create fake Power Registration.
  CreateFakeCppService<fuchsia_power_manager::DriverManagerRegistration>(
      svc_loop_state_->root, svc_loop_state_->loop.dispatcher(),
      std::make_unique<FakePowerRegistration>());

  CreateFakeCppService<fuchsia_sys2::Realm>(
      svc_loop_state_->root, svc_loop_state_->loop.dispatcher(), std::make_unique<FakeRealm>());

  // Serve VFS on channel.
  svc_loop_state_->vfs.ServeDirectory(svc_loop_state_->root, std::move(bootsvc_server),
                                      fs::Rights::ReadWrite());

  return svc_loop_state_->loop.StartThread("isolated-devmgr-svcloop");
}

__EXPORT
zx_status_t IsolatedDevmgr::AddDevfsToOutgoingDir(vfs::PseudoDir* outgoing_root_dir) {
  zx::channel client, server;
  auto status = zx::channel::create(0, &client, &server);
  if (status != ZX_OK) {
    return status;
  }
  fdio_cpp::UnownedFdioCaller fd(devfs_root_.get());
  fdio_service_clone_to(fd.borrow_channel(), server.release());

  // Add devfs to out directory.
  auto devfs_out = std::make_unique<vfs::RemoteDir>(std::move(client));
  outgoing_root_dir->AddEntry("dev", std::move(devfs_out));
  return ZX_OK;
}

__EXPORT
devmgr_launcher::Args IsolatedDevmgr::DefaultArgs() {
  devmgr_launcher::Args args;
  args.sys_device_driver = kSysdevDriver;
  args.load_drivers.push_back("/boot/driver/test.so");
  args.driver_search_paths.push_back("/boot/driver/test");
  return args;
}

__EXPORT
IsolatedDevmgr::IsolatedDevmgr() = default;

__EXPORT
IsolatedDevmgr::~IsolatedDevmgr() { Terminate(); }

__EXPORT
IsolatedDevmgr::IsolatedDevmgr(IsolatedDevmgr&& other)
    : job_(std::move(other.job_)),
      svc_root_dir_(std::move(other.svc_root_dir_)),
      fshost_outgoing_dir_(std::move(other.fshost_outgoing_dir_)),
      devfs_root_(std::move(other.devfs_root_)),
      component_lifecycle_client_(std::move(other.component_lifecycle_client_)),
      svc_loop_state_(std::move(other.svc_loop_state_)),
      exception_loop_state_(std::move(other.exception_loop_state_)) {}

__EXPORT
IsolatedDevmgr& IsolatedDevmgr::operator=(IsolatedDevmgr&& other) {
  Terminate();
  job_ = std::move(other.job_);
  component_lifecycle_client_ = std::move(other.component_lifecycle_client_);
  devfs_root_ = std::move(other.devfs_root_);
  svc_root_dir_ = std::move(other.svc_root_dir_);
  fshost_outgoing_dir_ = std::move(other.fshost_outgoing_dir_);
  svc_loop_state_ = std::move(other.svc_loop_state_);
  exception_loop_state_ = std::move(other.exception_loop_state_);
  return *this;
}

__EXPORT
void IsolatedDevmgr::Terminate() {
  if (job_.is_valid()) {
    job_.kill();

    // Best-effort; ignores error.
    zx_signals_t observed = 0;
    job_.wait_one(ZX_TASK_TERMINATED, zx::time::infinite(), &observed);
  }
  job_.reset();
}

__EXPORT
zx_status_t IsolatedDevmgr::Create(devmgr_launcher::Args args, IsolatedDevmgr* out) {
  return Create(std::move(args), nullptr, out);
}

__EXPORT
zx_status_t IsolatedDevmgr::Create(devmgr_launcher::Args args, async_dispatcher_t* dispatcher,
                                   IsolatedDevmgr* out) {
  auto svc_endpoints = fidl::CreateEndpoints<fuchsia_io::Directory>();
  if (!svc_endpoints.is_ok()) {
    return svc_endpoints.status_value();
  }
  auto [svc_client, svc_server] = *std::move(svc_endpoints);

  auto fshost_endpoints = fidl::CreateEndpoints<fuchsia_io::Directory>();
  if (!fshost_endpoints.is_ok()) {
    return fshost_endpoints.status_value();
  }
  auto [fshost_outgoing_client, fshost_outgoing_server] = *std::move(fshost_endpoints);

  GetBootItemFunction get_boot_item = std::move(args.get_boot_item);
  auto component_lifecycle = fidl::CreateEndpoints<fuchsia_process_lifecycle::Lifecycle>();
  if (!component_lifecycle.is_ok()) {
    return component_lifecycle.status_value();
  }

  IsolatedDevmgr devmgr;
  zx::channel devfs;
  fidl::ClientEnd<fuchsia_io::Directory> outgoing_svc_root;
  std::map<std::string, std::string> boot_args = std::move(args.boot_args);
  zx_status_t status = devmgr_launcher::Launch(std::move(args), svc_client.TakeChannel(),
                                               fshost_outgoing_server.TakeChannel(),
                                               component_lifecycle->server.TakeChannel(),
                                               &devmgr.job_, &devfs, &outgoing_svc_root.channel());
  if (status != ZX_OK) {
    return status;
  }

  zx::channel exception_channel;
  devmgr.containing_job().create_exception_channel(0, &exception_channel);

  status = devmgr.SetupExceptionLoop(dispatcher, std::move(exception_channel));
  if (status != ZX_OK) {
    return status;
  }

  status = devmgr.SetupSvcLoop(std::move(svc_server), CloneDirectory(fshost_outgoing_client),
                               std::move(get_boot_item), std::move(boot_args));
  if (status != ZX_OK) {
    return status;
  }

  int fd;
  status = fdio_fd_create(devfs.release(), &fd);
  if (status != ZX_OK) {
    return status;
  }
  devmgr.devfs_root_.reset(fd);
  devmgr.component_lifecycle_client_ = std::move(component_lifecycle->client);
  devmgr.svc_root_dir_ = std::move(outgoing_svc_root);
  devmgr.fshost_outgoing_dir_ = std::move(fshost_outgoing_client);
  *out = std::move(devmgr);
  return ZX_OK;
}

__EXPORT void IsolatedDevmgr::SetExceptionCallback(fit::closure exception_callback) {
  exception_loop_state_->exception_callback_ = std::move(exception_callback);
}

__EXPORT bool IsolatedDevmgr::crashed() const { return exception_loop_state_->crashed_; }

}  // namespace devmgr_integration_test
