// 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/service/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/service/common.h"
#include "services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.h"

namespace webrunner {
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(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());
  ignore_result(job.release());
}

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

}  // namespace webrunner
