// 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 <dirent.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/syslog/global.h>
#include <lib/trace-provider/provider.h>
#include <zircon/process.h>
#include <zircon/processargs.h>

#include <src/lib/files/directory.h>

#include "src/lib/fxl/command_line.h"
#include "src/sys/appmgr/appmgr.h"
#include "src/sys/appmgr/moniker.h"
#include "src/sys/lib/stdout-to-debuglog/cpp/stdout-to-debuglog.h"

namespace {

// Returns the set of service names that should be proxied to the root realm
// from appmgr's namespace
std::vector<std::string> RootRealmServices() {
  std::vector<std::string> res;
  bool success = files::ReadDirContents("/svc_for_sys", &res);
  if (!success) {
    FX_LOGS(WARNING) << "failed to read /svc_for_sys (" << errno
                     << "), not forwarding services to sys realm";
    return std::vector<std::string>();
  }
  return res;
}

// Creates a zircon socket and sets it to appmgr's stdin.
zx_status_t InitStdinSocket() {
  zx::socket reader, writer;
  // Create a socket pair for stdin. We'll just discard the writer so stdin always looks like it's
  // closed.
  zx_status_t status = zx::socket::create(0, &writer, &reader);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "failed to create stdin socket: " << zx_status_get_string(status);
    return status;
  }
  status = reader.replace(ZX_RIGHTS_BASIC | ZX_RIGHT_READ, &reader);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "failed to replace stdin reader: " << zx_status_get_string(status);
    return status;
  }
  fdio_t* io;
  status = fdio_create(reader.release(), &io);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "failed to create fdio struct for stdin reader: "
                   << zx_status_get_string(status);
  }
  int fd = fdio_bind_to_fd(io, STDIN_FILENO, STDIN_FILENO);
  if (fd != STDIN_FILENO) {
    FX_LOGS(ERROR) << "failed to bind socket to stdin";
    return ZX_ERR_BAD_STATE;
  }

  return ZX_OK;
}

}  // namespace

int main(int argc, char** argv) {
  // Appmgr can't connect to the logging service just yet. Fall back to stderr to not lose any logs
  // in the meantime.
  fx_logger_activate_fallback(fx_log_get_logger(), -1);

  // Wire up standard streams. This sends all stdout and stderr to the debuglog.
  // This is necessary, instead of using fuchsia.logger.LogSink, because we need
  // to get appmgr logs before v1 components are running.
  zx_status_t status = StdoutToDebuglog::Init();
  if (status != ZX_OK) {
    return status;
  }

  status = InitStdinSocket();
  if (status != ZX_OK) {
    return status;
  }

  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  auto pa_directory_request = zx_take_startup_handle(PA_DIRECTORY_REQUEST);

  zx::channel svc_for_sys_server, svc_for_sys_client;
  status = zx::channel::create(0, &svc_for_sys_server, &svc_for_sys_client);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "failed to create channel: " << zx_status_get_string(status);
    return status;
  }
  status =
      fdio_open("/svc_for_sys", ZX_FS_RIGHT_READABLE | ZX_FS_FLAG_DIRECTORY | ZX_FS_RIGHT_WRITABLE,
                svc_for_sys_server.release());
  if (status != ZX_OK) {
    FX_LOGS(WARNING) << "failed to open /svc_for_sys (" << zx_status_get_string(status)
                     << "), not forwarding services to sys realm";
    return status;
  }

  auto environment_services =
      std::make_shared<sys::ServiceDirectory>(std::move(svc_for_sys_client));

  // Certain services in appmgr's /svc, which is served by svchost, are added to
  // the root realm so they can be routed into a nested environment (such as the
  // sys realm in sysmgr) and used in components.
  fuchsia::sys::ServiceListPtr root_realm_services(new fuchsia::sys::ServiceList);
  root_realm_services->names = RootRealmServices();
  root_realm_services->host_directory = environment_services->CloneChannel().TakeChannel();

  zx::channel trace_client, trace_server;
  status = zx::channel::create(0, &trace_client, &trace_server);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "failed to create tracing channel: " << status;
    return status;
  }

  trace::TraceProvider trace_provider(std::move(trace_client), loop.dispatcher());

  auto lifecycle_request = zx_take_startup_handle(PA_LIFECYCLE);
  std::unordered_set<component::Moniker> lifecycle_allowlist;
  lifecycle_allowlist.insert(component::Moniker{
      .url = "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx", .realm_path = {"sys"}});
  lifecycle_allowlist.insert(component::Moniker{
      .url = "fuchsia-pkg://fuchsia.com/cobalt#meta/cobalt.cmx", .realm_path = {"sys"}});

  component::AppmgrArgs args{.pa_directory_request = std::move(pa_directory_request),
                             .lifecycle_request = std::move(lifecycle_request),
                             .lifecycle_allowlist = std::move(lifecycle_allowlist),
                             .root_realm_services = std::move(root_realm_services),
                             .environment_services = std::move(environment_services),
                             .sysmgr_url = "fuchsia-pkg://fuchsia.com/sysmgr#meta/sysmgr.cmx",
                             .sysmgr_args = {},
                             .run_virtual_console = true,
                             .trace_server_channel = std::move(trace_server),
                             .stop_callback = [](zx_status_t status) { exit(status); }};
  component::Appmgr appmgr(loop.dispatcher(), std::move(args));

  loop.Run();
  return 0;
}
