// Copyright 2018 The Chromium 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/engine/context_provider_impl.h"

#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async/default.h>
#include <lib/fdio/io.h>
#include <lib/fdio/util.h>
#include <lib/zx/job.h>
#include <stdio.h>
#include <zircon/processargs.h>

#include <utility>

#include "base/base_paths_fuchsia.h"
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/fuchsia/default_job.h"
#include "base/fuchsia/file_utils.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "fuchsia/engine/common.h"
#include "services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.h"

namespace {

// Relaunches the current executable as a Context process.
base::Process LaunchContextProcess(const base::CommandLine& launch_command,
                                   const base::LaunchOptions& launch_options) {
  return base::LaunchProcess(launch_command, launch_options);
}

// Returns true if |handle| is connected to a directory.
bool IsValidDirectory(zx_handle_t handle) {
  base::File directory =
      base::fuchsia::GetFileFromHandle(zx::handle(fdio_service_clone(handle)));
  if (!directory.IsValid())
    return false;

  base::File::Info info;
  if (!directory.GetInfo(&info)) {
    LOG(ERROR) << "Could not query FileInfo for handle.";
    directory.Close();
    return false;
  }

  if (!info.is_directory) {
    LOG(ERROR) << "Handle is not a directory.";
    return false;
  }

  return true;
}

}  // namespace

ContextProviderImpl::ContextProviderImpl() : ContextProviderImpl(false) {}

ContextProviderImpl::ContextProviderImpl(bool use_shared_tmp)
    : launch_(base::BindRepeating(&LaunchContextProcess)),
      use_shared_tmp_(use_shared_tmp) {}

ContextProviderImpl::~ContextProviderImpl() = default;

// static
std::unique_ptr<ContextProviderImpl> ContextProviderImpl::CreateForTest() {
  // Bind the unique_ptr in a two step process.
  // std::make_unique<> doesn't work well with private constructors,
  // and the unique_ptr(raw_ptr*) constructor format isn't permitted as per
  // PRESUBMIT.py policy.
  std::unique_ptr<ContextProviderImpl> provider;
  provider.reset(new ContextProviderImpl(true));
  return provider;
}

void ContextProviderImpl::SetLaunchCallbackForTests(
    const LaunchContextProcessCallback& launch) {
  launch_ = launch;
}

void ContextProviderImpl::Create(
    chromium::web::CreateContextParams params,
    ::fidl::InterfaceRequest<chromium::web::Context> context_request) {
  DCHECK(context_request.is_valid());

  base::CommandLine launch_command = *base::CommandLine::ForCurrentProcess();

  base::LaunchOptions launch_options;

  service_manager::SandboxPolicyFuchsia sandbox_policy;
  sandbox_policy.Initialize(service_manager::SANDBOX_TYPE_WEB_CONTEXT);
  sandbox_policy.SetServiceDirectory(
      fidl::InterfaceHandle<::fuchsia::io::Directory>(
          std::move(params.service_directory)));
  sandbox_policy.UpdateLaunchOptionsForSandbox(&launch_options);

  if (use_shared_tmp_)
    launch_options.paths_to_clone.push_back(base::FilePath("/tmp"));

  // Transfer the ContextRequest handle to a well-known location in the child
  // process' handle table.
  zx::channel context_handle(context_request.TakeChannel());
  launch_options.handles_to_transfer.push_back(
      {kContextRequestHandleId, context_handle.get()});

  // Bind |data_directory| to /data directory, if provided.
  if (params.data_directory) {
    if (!IsValidDirectory(params.data_directory.get()))
      return;

    base::FilePath data_path;
    CHECK(base::PathService::Get(base::DIR_APP_DATA, &data_path));
    launch_options.paths_to_transfer.push_back(
        base::PathToTransfer{data_path, params.data_directory.release()});
  }

  // Isolate the child Context processes by containing them within their own
  // respective jobs.
  zx::job job;
  zx_status_t status = zx::job::create(*base::GetDefaultJob(), 0, &job);
  ZX_CHECK(status == ZX_OK, status) << "zx_job_create";
  launch_options.job_handle = job.get();

  ignore_result(launch_.Run(std::move(launch_command), launch_options));

  ignore_result(context_handle.release());
}

void ContextProviderImpl::Bind(
    fidl::InterfaceRequest<chromium::web::ContextProvider> request) {
  bindings_.AddBinding(this, std::move(request));
}
