// 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 <fuchsia/boot/cpp/fidl.h>
#include <getopt.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/devmgr-launcher/processargs.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/io.h>
#include <lib/fit/optional.h>
#include <lib/zx/event.h>
#include <lib/zx/port.h>
#include <lib/zx/resource.h>
#include <lib/zx/vmo.h>
#include <threads.h>
#include <zircon/device/vfs.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/syscalls/policy.h>
#include <zircon/types.h>

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>

#include <fbl/string_printf.h>
#include <fs/managed_vfs.h>
#include <fs/pseudo_dir.h>
#include <fs/remote_dir.h>
#include <fs/vfs.h>
#include <fs/vmo_file.h>

#include "component_lifecycle.h"
#include "coordinator.h"
#include "devfs.h"
#include "driver_host_loader_service.h"
#include "fdio.h"
#include "src/devices/lib/log/log.h"
#include "src/sys/lib/stdout-to-debuglog/cpp/stdout-to-debuglog.h"
#include "system_instance.h"

namespace {

// These are helpers for getting sets of parameters over FIDL
struct DriverManagerParams {
  bool driver_host_asan;
  bool driver_host_strict_linking;
  bool log_to_debuglog;
  bool require_system;
  bool suspend_timeout_fallback;
  bool verbose;
};

DriverManagerParams GetDriverManagerParams(llcpp::fuchsia::boot::Arguments::SyncClient& client) {
  llcpp::fuchsia::boot::BoolPair bool_req[]{
      // TODO(bwb): remove this or figure out how to make it work
      {"devmgr.devhost.asan", false},
      {"devmgr.devhost.strict-linking", false},
      {"devmgr.log-to-debuglog", false},
      {"devmgr.require-system", false},
      // Turn it on by default. See fxb/34577
      {"devmgr.suspend-timeout-fallback", true},
      {"devmgr.verbose", false},
  };
  auto bool_resp = client.GetBools(fidl::unowned_vec(bool_req));
  if (!bool_resp.ok()) {
    return {};
  }
  return {bool_resp->values[0], bool_resp->values[1], bool_resp->values[2],
          bool_resp->values[3], bool_resp->values[4], bool_resp->values[5]};
}

static const std::string kRootJobPath = "/svc/" + std::string(fuchsia::boot::RootJob::Name_);
static const std::string kRootResourcePath =
    "/svc/" + std::string(fuchsia::boot::RootResource::Name_);

// Get the root job from the root job service.
zx_status_t get_root_job(zx::job* root_job) {
  fuchsia::boot::RootJobSyncPtr root_job_ptr;
  zx_status_t status = fdio_service_connect(kRootJobPath.c_str(),
                            root_job_ptr.NewRequest().TakeChannel().release());
  if (status != ZX_OK) {
    return status;
  }
  return root_job_ptr->Get(root_job);
}

// Get the root resource from the root resource service. Not receiving the
// startup handle is logged, but not fatal.  In test environments, it would not
// be present.
zx_status_t get_root_resource(zx::resource* root_resource) {
  fuchsia::boot::RootResourceSyncPtr root_resource_ptr;
  zx_status_t status = fdio_service_connect(kRootResourcePath.c_str(),
                            root_resource_ptr.NewRequest().TakeChannel().release());
  if (status != ZX_OK) {
    return status;
  }
  return root_resource_ptr->Get(root_resource);
}

void ParseArgs(int argc, char** argv, DevmgrArgs* out) {
  enum {
    kDriverSearchPath,
    kLoadDriver,
    kSysDeviceDriver,
    kNoStartSvchost,
    kDisableBlockWatcher,
    kDisableNetsvc,
    kLogToDebuglog,
  };
  option options[] = {
      {"driver-search-path", required_argument, nullptr, kDriverSearchPath},
      {"load-driver", required_argument, nullptr, kLoadDriver},
      {"sys-device-driver", required_argument, nullptr, kSysDeviceDriver},
      {"no-start-svchost", no_argument, nullptr, kNoStartSvchost},
      {"disable-block-watcher", no_argument, nullptr, kDisableBlockWatcher},
      {"disable-netsvc", no_argument, nullptr, kDisableNetsvc},
      {"log-to-debuglog", no_argument, nullptr, kLogToDebuglog},
  };

  auto print_usage_and_exit = [options]() {
    printf("driver_manager: supported arguments:\n");
    for (const auto& option : options) {
      printf("  --%s\n", option.name);
    }
    abort();
  };

  auto check_not_duplicated = [print_usage_and_exit](const char* arg) {
    if (arg != nullptr) {
      printf("driver_manager: duplicated argument\n");
      print_usage_and_exit();
    }
  };

  // Reset the args state
  *out = DevmgrArgs();

  int opt;
  while ((opt = getopt_long(argc, argv, "", options, nullptr)) != -1) {
    switch (opt) {
      case kDriverSearchPath:
        out->driver_search_paths.push_back(optarg);
        break;
      case kLoadDriver:
        out->load_drivers.push_back(optarg);
        break;
      case kSysDeviceDriver:
        check_not_duplicated(out->sys_device_driver);
        out->sys_device_driver = optarg;
        break;
      case kNoStartSvchost:
        out->start_svchost = false;
        break;
      case kDisableBlockWatcher:
        out->disable_block_watcher = true;
        break;
      case kDisableNetsvc:
        out->disable_netsvc = true;
        break;
      case kLogToDebuglog:
        out->log_to_debuglog = true;
        break;
      default:
        print_usage_and_exit();
    }
  }
}

zx_status_t CreateDriverHostJob(const zx::job& root_job, zx::job* driver_host_job_out) {
  zx::job driver_host_job;
  zx_status_t status = zx::job::create(root_job, 0u, &driver_host_job);
  if (status != ZX_OK) {
    LOGF(ERROR, "Unable to create driver_host job: %s", zx_status_get_string(status));
    return status;
  }
  static const zx_policy_basic_v2_t policy[] = {
      {ZX_POL_BAD_HANDLE, ZX_POL_ACTION_ALLOW_EXCEPTION, ZX_POL_OVERRIDE_DENY},
  };
  status = driver_host_job.set_policy(ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC_V2, &policy,
                                      fbl::count_of(policy));
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to set driver_host job policy: %s", zx_status_get_string(status));
    return status;
  }
  status = driver_host_job.set_property(ZX_PROP_NAME, "zircon-drivers", 15);
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to set driver_host job property: %s", zx_status_get_string(status));
    return status;
  }

  *driver_host_job_out = std::move(driver_host_job);
  return ZX_OK;
}

}  // namespace

int main(int argc, char** argv) {
  zx_status_t status = StdoutToDebuglog::Init();
  if (status != ZX_OK) {
    LOGF(INFO, "Failed to redirect stdout to debuglog, assuming test environment and continuing");
  }

  zx::channel local, remote;
  status = zx::channel::create(0, &local, &remote);
  if (status != ZX_OK) {
    return status;
  }
  auto path = fbl::StringPrintf("/svc/%s", llcpp::fuchsia::boot::Arguments::Name);
  status = fdio_service_connect(path.data(), remote.release());
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to get boot arguments service handle: %s", zx_status_get_string(status));
    return status;
  }

  auto boot_args = llcpp::fuchsia::boot::Arguments::SyncClient{std::move(local)};
  auto driver_manager_params = GetDriverManagerParams(boot_args);
  DevmgrArgs devmgr_args;
  ParseArgs(argc, argv, &devmgr_args);

  if (driver_manager_params.verbose) {
    FX_LOG_SET_VERBOSITY(1);
  }
  if (driver_manager_params.log_to_debuglog || devmgr_args.log_to_debuglog) {
    zx_status_t status = log_to_debuglog();
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to reconfigure logger to use debuglog: %s", zx_status_get_string(status));
      return status;
    }
  }
  // Set up the default values for our arguments if they weren't given.
  if (devmgr_args.driver_search_paths.size() == 0) {
    devmgr_args.driver_search_paths.push_back("/boot/driver");
  }
  if (devmgr_args.sys_device_driver == nullptr) {
    devmgr_args.sys_device_driver = "/boot/driver/platform-bus.so";
  }

  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  CoordinatorConfig config{};
  SystemInstance system_instance;
  config.dispatcher = loop.dispatcher();
  config.boot_args = &boot_args;
  config.require_system = driver_manager_params.require_system;
  config.asan_drivers = driver_manager_params.driver_host_asan;
  config.suspend_fallback = driver_manager_params.suspend_timeout_fallback;
  config.log_to_debuglog = driver_manager_params.log_to_debuglog || devmgr_args.log_to_debuglog;
  config.verbose = driver_manager_params.verbose;
  config.disable_netsvc = devmgr_args.disable_netsvc;
  config.fs_provider = &system_instance;

  // TODO(ZX-4178): Remove all uses of the root resource.
  status = get_root_resource(&config.root_resource);
  if (status != ZX_OK) {
    LOGF(INFO, "Failed to get root resource, assuming test environment and continuing");
  }
  // TODO(ZX-4177): Remove all uses of the root job.
  zx::job root_job;
  status = get_root_job(&root_job);
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to get root job: %s", zx_status_get_string(status));
    return status;
  }
  status = CreateDriverHostJob(root_job, &config.driver_host_job);
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to create driver_host job: %s", zx_status_get_string(status));
    return status;
  }

  zx_handle_t oom_event;
  status = zx_system_get_event(root_job.get(), ZX_SYSTEM_EVENT_OUT_OF_MEMORY, &oom_event);
  if (status != ZX_OK) {
    LOGF(INFO, "Failed to get OOM event, assuming test environment and continuing");
  } else {
    config.oom_event = zx::event(oom_event);
  }

  Coordinator coordinator(std::move(config));

  // Services offered to the rest of the system.
  svc::Outgoing outgoing{loop.dispatcher()};
  status = coordinator.InitOutgoingServices(outgoing.svc_dir());
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to initialize outgoing services: %s", zx_status_get_string(status));
    return status;
  }

  // Check if whatever launched devcoordinator gave a channel to be connected to the
  // outgoing services directory. This is for use in tests to let the test environment see
  // outgoing services.
  zx::channel outgoing_svc_dir_client(
      zx_take_startup_handle(DEVMGR_LAUNCHER_OUTGOING_SERVICES_HND));
  if (outgoing_svc_dir_client.is_valid()) {
    status = outgoing.Serve(std::move(outgoing_svc_dir_client));
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to bind outgoing services: %s", zx_status_get_string(status));
      return status;
    }
  }

  status = coordinator.InitCoreDevices(devmgr_args.sys_device_driver);
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to initialize core devices: %s", zx_status_get_string(status));
    return status;
  }

  devfs_init(coordinator.root_device(), loop.dispatcher());
  devfs_publish(coordinator.root_device(), coordinator.misc_device());
  devfs_publish(coordinator.root_device(), coordinator.sys_device());
  devfs_publish(coordinator.root_device(), coordinator.test_device());
  devfs_connect_diagnostics(coordinator.inspect_manager().diagnostics_channel());

  // Check if whatever launched devmgr gave a channel to be connected to /dev.
  // This is for use in tests to let the test environment see devfs.
  zx::channel devfs_client(zx_take_startup_handle(DEVMGR_LAUNCHER_DEVFS_ROOT_HND));
  if (devfs_client.is_valid()) {
    fdio_service_clone_to(devfs_root_borrow()->get(), devfs_client.release());
  }

  // Check if whatever launched devmgr gave a channel for component lifecycle events
  zx::channel component_lifecycle_request(zx_take_startup_handle(PA_LIFECYCLE));
  ZX_ASSERT(component_lifecycle_request.is_valid());
  if (component_lifecycle_request.is_valid()) {
    status = devmgr::ComponentLifecycleServer::Create(loop.dispatcher(), &coordinator,
                                                      std::move(component_lifecycle_request));
    if (status != ZX_OK) {
      LOGF(ERROR, "driver_manager: Cannot create componentlifecycleserver: %s\n",
           zx_status_get_string(status));
      return status;
    }
  }

  status = system_instance.CreateSvcJob(root_job);
  if (status != ZX_OK) {
    return status;
  }

  status = system_instance.PrepareChannels();
  if (status != ZX_OK) {
    LOGF(ERROR, "Failed to create other system channels: %s", zx_status_get_string(status));
    return status;
  }

  if (devmgr_args.start_svchost) {
    zx::channel root_server, root_client;
    status = zx::channel::create(0, &root_server, &root_client);
    if (status != ZX_OK) {
      return status;
    }
    status = outgoing.Serve(std::move(root_server));
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to bind outgoing services: %s", zx_status_get_string(status));
      return status;
    }
    status = system_instance.StartSvchost(root_job, root_client,
                                          driver_manager_params.require_system, &coordinator);
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to start svchost: %s", zx_status_get_string(status));
      return status;
    }
  } else {
    status = system_instance.ReuseExistingSvchost();
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to reuse existing svchost: %s", zx_status_get_string(status));
      return status;
    }
  }

  system_instance.devmgr_vfs_init();

  thrd_t t;

  auto pwrbtn_starter_args = std::make_unique<SystemInstance::ServiceStarterArgs>();
  pwrbtn_starter_args->instance = &system_instance;
  pwrbtn_starter_args->coordinator = &coordinator;
  int ret = thrd_create_with_name(&t, SystemInstance::pwrbtn_monitor_starter,
                                  pwrbtn_starter_args.release(), "pwrbtn-monitor-starter");
  if (ret != thrd_success) {
    LOGF(ERROR, "Failed to create pwrbtn monitor starter thread: %d", ret);
    return ret;
  }
  thrd_detach(t);

  system_instance.start_console_shell(boot_args);

  auto service_starter_args = std::make_unique<SystemInstance::ServiceStarterArgs>();
  service_starter_args->instance = &system_instance;
  service_starter_args->coordinator = &coordinator;
  ret = thrd_create_with_name(&t, SystemInstance::service_starter, service_starter_args.release(),
                              "service-starter");
  if (ret != thrd_success) {
    LOGF(ERROR, "Failed to create service starter thread: %d", ret);
    return ret;
  }
  thrd_detach(t);

  if (driver_manager_params.driver_host_strict_linking) {
    std::unique_ptr<DriverHostLoaderService> loader_service;
    status = DriverHostLoaderService::Create(loop.dispatcher(), &system_instance, &loader_service);
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to create loader service: %s", zx_status_get_string(status));
      return status;
    }
    coordinator.set_loader_service_connector([ls = std::move(loader_service)](zx::channel* c) {
      zx_status_t status = ls->Connect(c);
      if (status != ZX_OK) {
        LOGF(ERROR, "Failed to add driver_host loader connection: %s",
             zx_status_get_string(status));
      }
      return status;
    });
  } else {
    coordinator.set_loader_service_connector([&system_instance](zx::channel* c) {
      zx_status_t status = system_instance.clone_fshost_ldsvc(c);
      if (status != ZX_OK) {
        LOGF(ERROR, "Failed to clone fshost loader for driver_host: %s",
             zx_status_get_string(status));
      }
      return status;
    });
  }

  for (const char* path : devmgr_args.driver_search_paths) {
    find_loadable_drivers(path, fit::bind_member(&coordinator, &Coordinator::DriverAddedInit));
  }
  for (const char* driver : devmgr_args.load_drivers) {
    load_driver(driver, fit::bind_member(&coordinator, &Coordinator::DriverAddedInit));
  }

  if (coordinator.require_system() && !coordinator.system_loaded()) {
    LOGF(INFO, "Full system required, ignoring fallback drivers until '/system' is loaded");
  } else {
    coordinator.UseFallbackDrivers();
  }

  coordinator.PrepareProxy(coordinator.sys_device(), nullptr);
  coordinator.PrepareProxy(coordinator.test_device(), nullptr);
  // Initial bind attempt for drivers enumerated at startup.
  coordinator.BindDrivers();

  // Expose /dev directory for use in sysinfo service; specifically to connect to /dev/sys/platform
  auto outgoing_dir = fbl::MakeRefCounted<fs::PseudoDir>();
  outgoing_dir->AddEntry("dev", fbl::MakeRefCounted<fs::RemoteDir>(system_instance.CloneFs("dev")));
  outgoing_dir->AddEntry("svc", fbl::MakeRefCounted<fs::RemoteDir>(system_instance.CloneFs("svc")));

  fs::ManagedVfs outgoing_vfs = fs::ManagedVfs(loop.dispatcher());
  outgoing_vfs.ServeDirectory(outgoing_dir,
                              zx::channel(zx_take_startup_handle(PA_DIRECTORY_REQUEST)));

  coordinator.set_running(true);
  status = loop.Run();
  LOGF(ERROR, "Coordinator exited unexpectedly: %s", zx_status_get_string(status));
  return status;
}
