// Copyright 2020 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 "bind_devfs_to_namespace.h"

#include <fuchsia/sys2/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/namespace.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/types.h>

namespace isolated_devmgr {

zx::status<> OneTimeSetUp() {
  static zx::status<> status = []() -> zx::status<> {
    // Mark this process as critical so that if this process terminates, all other processes
    // within this job get terminated (e.g. file system processes).
    auto status = zx::make_status(zx::job::default_job()->set_critical(0, *zx::process::self()));
    if (status.is_error()) {
      FX_LOGS(ERROR) << "Unable to make process critical: " << status.status_string();
      return status;
    }
    status = isolated_devmgr::BindDevfsToNamespace();
    if (status.is_error()) {
      FX_LOGS(ERROR) << "Unable to bind devfs to namespace: " << status.status_string();
      return status;
    }
    return zx::ok();
  }();
  return status;
}

zx::status<> BindDevfsToNamespace() {
  fdio_ns_t* name_space;
  auto status = zx::make_status(fdio_ns_get_installed(&name_space));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Failed to get namespace: " << status.status_string();
    return status;
  }
  fidl::SynchronousInterfacePtr<fuchsia::sys2::Realm> realm;
  std::string service_name = std::string("/svc/") + fuchsia::sys2::Realm::Name_;
  status = zx::make_status(
      fdio_service_connect(service_name.c_str(), realm.NewRequest().TakeChannel().get()));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Unable to connect to realm service: " << status.status_string();
    return status;
  }
  fidl::SynchronousInterfacePtr<fuchsia::io::Directory> exposed_dir;
  fuchsia::sys2::Realm_BindChild_Result result;
  status = zx::make_status(realm->BindChild(fuchsia::sys2::ChildRef{.name = "isolated-devmgr"},
                                            exposed_dir.NewRequest(), &result));
  if (status.is_error() || result.is_err()) {
    FX_LOGS(ERROR) << "Unable to connect to child: " << status.status_string();
    return status;
  }
  zx::channel handle, request;
  status = zx::make_status(zx::channel::create(0, &handle, &request));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Unable to create channel: " << status.status_string();
    return status;
  }
  status = zx::make_status(
      exposed_dir->Open(fuchsia::io::OPEN_FLAG_DIRECTORY | fuchsia::io::OPEN_RIGHT_READABLE,
                        fuchsia::io::MODE_TYPE_DIRECTORY, "dev",
                        fidl::InterfaceRequest<fuchsia::io::Node>(std::move(request))));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Unable to open dev in child: " << status.status_string();
    return status;
  }
  status = zx::make_status(fdio_ns_bind(name_space, "/dev", handle.release()));
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Failed to bind /dev to namespace: " << status.status_string();
    return status;
  }
  return zx::ok();
}

}  // namespace isolated_devmgr
