// 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 "managed_launcher.h"
#include <lib/component/cpp/testing/test_util.h>
#include <lib/fdio/io.h>
#include <lib/fsl/io/fd.h>
#include <lib/fxl/files/unique_fd.h>
#include <lib/fxl/logging.h>
#include <lib/fxl/strings/concatenate.h>
#include <lib/pkg_url/fuchsia_pkg_url.h>
#include <zircon/status.h>
#include "garnet/lib/cmx/cmx.h"
#include "garnet/lib/process/process_builder.h"
#include "managed_environment.h"

namespace netemul {

using fuchsia::sys::TerminationReason;
using process::ProcessBuilder;

static const char* kVdevRoot = "/vdev";
static const char* kVDataRoot = "/vdata";

static void CreateFlatNamespace(fuchsia::sys::LaunchInfo* linfo) {
  if (!linfo->flat_namespace) {
    linfo->flat_namespace = std::make_unique<fuchsia::sys::FlatNamespace>();
  }
}

struct LaunchArgs {
  fuchsia::sys::LaunchInfo launch_info;
  fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller;
};

void ManagedLauncher::CreateComponent(
    fuchsia::sys::LaunchInfo launch_info,
    fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
  // because fuchsia.sys.loader uses legacy callbacks, we need to
  // save the info in a shared ptr for the closure
  auto args = std::make_shared<LaunchArgs>();
  args->launch_info = std::move(launch_info);
  args->controller = std::move(controller);

  // load package information
  loader_->LoadUrl(
      args->launch_info.url, [this, args](fuchsia::sys::PackagePtr package) {
        CreateComponent(std::move(package), std::move(args->launch_info),
                        std::move(args->controller));
      });
}

ManagedLauncher::ManagedLauncher(ManagedEnvironment* environment)
    : env_(environment) {
  env_->environment().ConnectToService(real_launcher_.NewRequest());
  env_->environment().ConnectToService(loader_.NewRequest());
}

void ManagedLauncher::Bind(
    fidl::InterfaceRequest<fuchsia::sys::Launcher> request) {
  bindings_.AddBinding(this, std::move(request));
}

void ManagedLauncher::CreateComponent(
    fuchsia::sys::PackagePtr package, fuchsia::sys::LaunchInfo launch_info,
    fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
  // Before launching, we'll check the component's sandbox
  // so we can inject virtual devices
  if (!package) {
    FXL_LOG(ERROR) << "Can't load package " << launch_info.url;
    return;
  }

  if (!package->directory.is_valid()) {
    FXL_LOG(ERROR) << "Package directory not provided";
    return;
  }

  // let's open and parse the cmx
  component::FuchsiaPkgUrl fp;
  if (!fp.Parse(package->resolved_url)) {
    FXL_LOG(ERROR) << "Can't parse package url " << package->resolved_url;
    return;
  }

  component::CmxMetadata cmx;
  fxl::UniqueFD fd =
      fsl::OpenChannelAsFileDescriptor(std::move(package->directory));

  json::JSONParser json_parser;
  if (!cmx.ParseFromFileAt(fd.get(), fp.resource_path(), &json_parser)) {
    FXL_LOG(ERROR) << "cmx file failed to parse: " << json_parser.error_str();
    return;
  }

  // we have devices in sandbox meta, here
  // we just add our own /vdev to the flat namespace
  // this could be improved by filtering /vdev to requested classes only
  // like appmgr does,
  // but seems overkill for testing environments
  if (!cmx.sandbox_meta().dev().empty()) {
    CreateFlatNamespace(&launch_info);
    // add all devices to flat namespace:
    launch_info.flat_namespace->paths.push_back(kVdevRoot);
    launch_info.flat_namespace->directories.push_back(
        env_->OpenVdevDirectory());
  }

  if (cmx.sandbox_meta().HasFeature("persistent-storage")) {
    CreateFlatNamespace(&launch_info);
    // add virtual data folder (in-memory fs) to namespace
    launch_info.flat_namespace->paths.push_back(kVDataRoot);
    launch_info.flat_namespace->directories.push_back(
        env_->OpenVdataDirectory());
  }

  if (!launch_info.out) {
    launch_info.out = component::testing::CloneFileDescriptor(STDOUT_FILENO);
  }
  if (!launch_info.err) {
    launch_info.err = component::testing::CloneFileDescriptor(STDERR_FILENO);
  }

  real_launcher_->CreateComponent(std::move(launch_info),
                                  std::move(controller));
}

ManagedLauncher::~ManagedLauncher() = default;

}  // namespace netemul
