// Copyright 2017 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 <errno.h>
#include <fcntl.h>
#include <fuchsia/boot/c/fidl.h>
#include <fuchsia/fshost/llcpp/fidl.h>
#include <fuchsia/io/llcpp/fidl.h>
#include <fuchsia/ldsvc/c/fidl.h>
#include <getopt.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/namespace.h>
#include <lib/fdio/watcher.h>
#include <lib/fidl-async/cpp/bind.h>
#include <lib/fit/defer.h>
#include <lib/zx/channel.h>
#include <stdio.h>
#include <zircon/boot/image.h>
#include <zircon/device/vfs.h>
#include <zircon/dlfcn.h>
#include <zircon/processargs.h>
#include <zircon/status.h>

#include <memory>
#include <thread>

#include <cobalt-client/cpp/collector.h>
#include <fbl/unique_fd.h>
#include <fs/remote_dir.h>
#include <fs/service.h>
#include <ramdevice-client/ramdisk.h>
#include <zbi-bootfs/zbi-bootfs.h>

#include "block-watcher.h"
#include "fs-manager.h"
#include "metrics.h"
#include "src/storage/fshost/deprecated-loader-service.h"
#include "src/sys/lib/stdout-to-debuglog/cpp/stdout-to-debuglog.h"

namespace fio = ::llcpp::fuchsia::io;

namespace devmgr {
namespace {

// local_storage project ID as defined in cobalt-analytics projects.yaml.
constexpr uint32_t kCobaltProjectId = 3676913920;

FsHostMetrics MakeMetrics() {
  return FsHostMetrics(std::make_unique<cobalt_client::Collector>(kCobaltProjectId));
}

constexpr char kItemsPath[] = "/svc/" fuchsia_boot_Items_Name;

// Get ramdisk from the boot items service.
zx_status_t get_ramdisk(zx::vmo* ramdisk_vmo) {
  zx::channel local, remote;
  zx_status_t status = zx::channel::create(0, &local, &remote);
  if (status != ZX_OK) {
    return status;
  }
  status = fdio_service_connect(kItemsPath, remote.release());
  if (status != ZX_OK) {
    return status;
  }
  uint32_t length;
  return fuchsia_boot_ItemsGet(local.get(), ZBI_TYPE_STORAGE_RAMDISK, 0,
                               ramdisk_vmo->reset_and_get_address(), &length);
}

zx_status_t MiscDeviceAdded(int dirfd, int event, const char* fn, void* cookie) {
  if (event != WATCH_EVENT_ADD_FILE || strcmp(fn, "ramctl") != 0) {
    return ZX_OK;
  }

  zx::vmo ramdisk_vmo(static_cast<zx_handle_t>(reinterpret_cast<uintptr_t>(cookie)));

  zbi_header_t header;
  zx_status_t status = ramdisk_vmo.read(&header, 0, sizeof(header));
  if (status != ZX_OK) {
    printf("fshost: cannot read ZBI_TYPE_STORAGE_RAMDISK item header: %s\n",
           zx_status_get_string(status));
    return ZX_ERR_STOP;
  }
  if (!(header.flags & ZBI_FLAG_VERSION) || header.magic != ZBI_ITEM_MAGIC ||
      header.type != ZBI_TYPE_STORAGE_RAMDISK) {
    printf("fshost: invalid ZBI_TYPE_STORAGE_RAMDISK item header\n");
    return ZX_ERR_STOP;
  }

  zx::vmo vmo;
  if (header.flags & ZBI_FLAG_STORAGE_COMPRESSED) {
    status = zx::vmo::create(header.extra, 0, &vmo);
    if (status != ZX_OK) {
      printf("fshost: cannot create VMO for uncompressed RAMDISK: %s\n",
             zx_status_get_string(status));
      return ZX_ERR_STOP;
    }
    status = zbi_bootfs::Decompress(ramdisk_vmo, sizeof(zbi_header_t), header.length, vmo, 0,
                                    header.extra);
    if (status != ZX_OK) {
      printf("fshost: failed to decompress RAMDISK: %s\n", zx_status_get_string(status));
      return ZX_ERR_STOP;
    }
  } else {
    // TODO(fxbug.dev/34597): The old code ignored uncompressed items too, and
    // silently.  Really the protocol should be cleaned up so the VMO arrives
    // without the header in it and then it could just be used here directly
    // if uncompressed (or maybe bootsvc deals with decompression in the first
    // place so the uncompressed VMO is always what we get).
    printf("fshost: ignoring uncompressed RAMDISK item in ZBI\n");
    return ZX_ERR_STOP;
  }

  ramdisk_client* client;
  status = ramdisk_create_from_vmo(vmo.release(), &client);
  if (status != ZX_OK) {
    printf("fshost: failed to create ramdisk from ZBI_TYPE_STORAGE_RAMDISK\n");
  } else {
    printf("fshost: ZBI_TYPE_STORAGE_RAMDISK attached\n");
  }
  return ZX_ERR_STOP;
}

int RamctlWatcher(void* arg) {
  fbl::unique_fd dirfd(open("/dev/misc", O_DIRECTORY | O_RDONLY));
  if (!dirfd) {
    printf("fshost: failed to open /dev/misc: %s\n", strerror(errno));
    return -1;
  }
  fdio_watch_directory(dirfd.get(), &MiscDeviceAdded, ZX_TIME_INFINITE, arg);
  return 0;
}

int BlockWatcher(std::unique_ptr<devmgr::FsManager> fs_manager) {
  // Check relevant boot arguments
  devmgr::BlockWatcherOptions options = {};
  options.netboot = fs_manager->boot_args()->netboot();
  options.check_filesystems = fs_manager->boot_args()->check_filesystems();
  options.wait_for_data = fs_manager->boot_args()->wait_for_data();

  if (options.netboot) {
    printf("fshost: disabling automount\n");
  }

  BlockDeviceWatcher(std::move(fs_manager), options);
  return 0;
}

// Initialize the fshost namespace.
//
// |fs_root_client| is mapped to "/fs", and represents the filesystem of devmgr.
zx_status_t BindNamespace(zx::channel fs_root_client) {
  fdio_ns_t* ns;
  zx_status_t status;
  if ((status = fdio_ns_get_installed(&ns)) != ZX_OK) {
    printf("fshost: cannot get namespace: %d\n", status);
    return status;
  }

  // Bind "/fs".
  if ((status = fdio_ns_bind(ns, "/fs", fs_root_client.release())) != ZX_OK) {
    printf("fshost: cannot bind /fs to namespace: %d\n", status);
    return status;
  }

  // Bind "/system".
  {
    zx::channel client, server;
    if ((status = zx::channel::create(0, &client, &server)) != ZX_OK) {
      return status;
    }
    if ((status = fdio_open("/fs/system",
                            ZX_FS_RIGHT_READABLE | ZX_FS_RIGHT_EXECUTABLE | ZX_FS_RIGHT_ADMIN,
                            server.release())) != ZX_OK) {
      printf("fshost: cannot open connection to /system: %d\n", status);
      return status;
    }
    if ((status = fdio_ns_bind(ns, "/system", client.release())) != ZX_OK) {
      printf("fshost: cannot bind /system to namespace: %d\n", status);
      return status;
    }
  }
  return ZX_OK;
}

}  // namespace
}  // namespace devmgr

int main(int argc, char** argv) {
  bool disable_block_watcher = false;
  bool log_to_debuglog = false;

  enum {
    kDisableBlockWatcher,
    kLogToDebuglog,
  };
  option options[] = {
      {"disable-block-watcher", no_argument, nullptr, kDisableBlockWatcher},
      {"log-to-debuglog", no_argument, nullptr, kLogToDebuglog},
  };

  int opt;
  while ((opt = getopt_long(argc, argv, "", options, nullptr)) != -1) {
    switch (opt) {
      case kDisableBlockWatcher:
        printf("fshost: received --disable-block-watcher\n");
        disable_block_watcher = true;
        break;
      case kLogToDebuglog:
        log_to_debuglog = true;
        break;
    }
  }

  if (log_to_debuglog) {
    zx_status_t status = StdoutToDebuglog::Init();
    if (status != ZX_OK) {
      return status;
    }
  }

  // Setup the fshost loader service, which can load libraries from either /system/lib or /boot/lib.
  // TODO(fxbug.dev/34633): This loader is DEPRECATED and should be deleted. Do not add new usages.
  async::Loop loader_loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  zx_status_t status = loader_loop.StartThread("fshost-loader");
  if (status != ZX_OK) {
    fprintf(stderr, "fshost: failed to start loader thread: %s\n", zx_status_get_string(status));
    return status;
  }
  fbl::unique_fd root_fd;
  status = fdio_open_fd(
      "/", fio::OPEN_FLAG_DIRECTORY | fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_EXECUTABLE,
      root_fd.reset_and_get_address());
  if (status != ZX_OK) {
    fprintf(stderr, "fshost: failed to open namespace root: %s\n", zx_status_get_string(status));
    return status;
  }
  auto loader = DeprecatedBootSystemLoaderService::Create(loader_loop.dispatcher(),
                                                          std::move(root_fd), "fshost");

  // Replace default loader service with a connection to our own.
  // TODO(bryanhenry): This is unnecessary and will be removed in a subsequent change. Left in to
  // minimize behavior differences per change.
  auto conn = loader->Connect();
  if (conn.is_error()) {
    fprintf(stderr, "fshost: failed to create loader connection: %s\n", conn.status_string());
    return conn.status_value();
  }
  zx_handle_close(dl_set_loader_service(std::move(conn).value().release()));

  // Initialize the local filesystem in isolation.
  zx::channel dir_request(zx_take_startup_handle(PA_DIRECTORY_REQUEST));
  zx::channel lifecycle_request(zx_take_startup_handle(PA_LIFECYCLE));
  std::unique_ptr<devmgr::FsManager> fs_manager;
  status =
      devmgr::FsManager::Create(std::move(loader), std::move(dir_request),
                                std::move(lifecycle_request), devmgr::MakeMetrics(), &fs_manager);
  if (status != ZX_OK) {
    printf("fshost: Cannot create FsManager: %s\n", zx_status_get_string(status));
    return status;
  }

  // Serve the root filesystems in our own namespace.
  zx::channel fs_root_client, fs_root_server;
  status = zx::channel::create(0, &fs_root_client, &fs_root_server);
  if (status != ZX_OK) {
    return ZX_OK;
  }
  status = fs_manager->ServeRoot(std::move(fs_root_server));
  if (status != ZX_OK) {
    printf("fshost: Cannot serve devmgr's root filesystem\n");
    return status;
  }

  // Initialize namespace, and begin monitoring for a termination event.
  status = devmgr::BindNamespace(std::move(fs_root_client));
  if (status != ZX_OK) {
    printf("fshost: cannot bind namespace\n");
    return status;
  }
  // TODO(dgonyeo): call WatchExit from inside FsManager, instead of doing it
  // here.
  fs_manager->WatchExit();

  // If there is a ramdisk, setup the ramctl filesystems.
  zx::vmo ramdisk_vmo;
  status = devmgr::get_ramdisk(&ramdisk_vmo);
  if (status != ZX_OK) {
    printf("fshost: failed to get ramdisk: %s\n", zx_status_get_string(status));
  } else if (ramdisk_vmo.is_valid()) {
    thrd_t t;

    int err = thrd_create_with_name(
        &t, &devmgr::RamctlWatcher,
        reinterpret_cast<void*>(static_cast<uintptr_t>(ramdisk_vmo.release())),
        "ramctl-filesystems");
    if (err != thrd_success) {
      printf("fshost: failed to start ramctl-filesystems: %d\n", err);
    }
    thrd_detach(t);
  }

  if (!disable_block_watcher) {
    std::thread t(&devmgr::BlockWatcher, std::move(fs_manager));
    t.detach();
  }

  zx::nanosleep(zx::time::infinite());

  printf("fshost: terminating (block device filesystems finished?)\n");
  return 0;
}
