// Copyright 2018 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "test/multiprocess_exec.h"

#include <launchpad/launchpad.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include "base/files/scoped_file.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/scoped_zx_handle.h"
#include "gtest/gtest.h"

namespace crashpad {
namespace test {

namespace internal {

struct MultiprocessInfo {
  MultiprocessInfo() {}
  base::ScopedFD stdin_write;
  base::ScopedFD stdout_read;
  base::ScopedZxHandle child;
};

}  // namespace internal

Multiprocess::Multiprocess()
    : info_(nullptr),
      code_(EXIT_SUCCESS),
      reason_(kTerminationNormal) {
}

void Multiprocess::Run() {
  // Set up and spawn the child process.
  ASSERT_NO_FATAL_FAILURE(PreFork());
  RunChild();

  // And then run the parent actions in this process.
  RunParent();

  // Wait until the child exits.
  zx_signals_t signals;
  ASSERT_EQ(
      zx_object_wait_one(
          info_->child.get(), ZX_TASK_TERMINATED, ZX_TIME_INFINITE, &signals),
      ZX_OK);
  ASSERT_EQ(signals, ZX_TASK_TERMINATED);

  // Get the child's exit code.
  zx_info_process_t proc_info;
  zx_status_t status = zx_object_get_info(info_->child.get(),
                                          ZX_INFO_PROCESS,
                                          &proc_info,
                                          sizeof(proc_info),
                                          nullptr,
                                          nullptr);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "zx_object_get_info";
    ADD_FAILURE() << "Unable to get exit code of child";
  } else {
    if (code_ != proc_info.return_code) {
      ADD_FAILURE() << "Child exited with code " << proc_info.return_code
                    << ", expected exit with code " << code_;
    }
  }
}

void Multiprocess::SetExpectedChildTermination(TerminationReason reason,
                                               int code) {
  EXPECT_EQ(info_, nullptr)
      << "SetExpectedChildTermination() must be called before Run()";
  reason_ = reason;
  code_ = code;
}

Multiprocess::~Multiprocess() {
  delete info_;
}

FileHandle Multiprocess::ReadPipeHandle() const {
  return info_->stdout_read.get();
}

FileHandle Multiprocess::WritePipeHandle() const {
  return info_->stdin_write.get();
}

void Multiprocess::CloseReadPipe() {
  info_->stdout_read.reset();
}

void Multiprocess::CloseWritePipe() {
  info_->stdin_write.reset();
}

void Multiprocess::RunParent() {
  MultiprocessParent();

  info_->stdout_read.reset();
  info_->stdin_write.reset();
}

void Multiprocess::RunChild() {
  MultiprocessChild();
}

MultiprocessExec::MultiprocessExec()
    : Multiprocess(), command_(), arguments_(), argv_() {
}

void MultiprocessExec::SetChildCommand(
    const base::FilePath& command,
    const std::vector<std::string>* arguments) {
  command_ = command;
  if (arguments) {
    arguments_ = *arguments;
  } else {
    arguments_.clear();
  }
}

MultiprocessExec::~MultiprocessExec() {}

void MultiprocessExec::PreFork() {
  ASSERT_FALSE(command_.empty());

  ASSERT_TRUE(argv_.empty());

  argv_.push_back(command_.value().c_str());
  for (const std::string& argument : arguments_) {
    argv_.push_back(argument.c_str());
  }

  ASSERT_EQ(info(), nullptr);
  set_info(new internal::MultiprocessInfo());
}

void MultiprocessExec::MultiprocessChild() {
  launchpad_t* lp;
  launchpad_create(zx_job_default(), command_.value().c_str(), &lp);
  launchpad_load_from_file(lp, command_.value().c_str());
  launchpad_set_args(lp, argv_.size(), &argv_[0]);

  // Pass the filesystem namespace, parent environment, and default job to the
  // child, but don't include any other file handles, preferring to set them
  // up explicitly below.
  launchpad_clone(
      lp, LP_CLONE_FDIO_NAMESPACE | LP_CLONE_ENVIRON | LP_CLONE_DEFAULT_JOB);

  int stdin_parent_side;
  launchpad_add_pipe(lp, &stdin_parent_side, STDIN_FILENO);
  info()->stdin_write.reset(stdin_parent_side);

  int stdout_parent_side;
  launchpad_add_pipe(lp, &stdout_parent_side, STDOUT_FILENO);
  info()->stdout_read.reset(stdout_parent_side);

  launchpad_clone_fd(lp, STDERR_FILENO, STDERR_FILENO);

  const char* error_message;
  zx_handle_t child;
  zx_status_t status = launchpad_go(lp, &child, &error_message);
  ZX_CHECK(status == ZX_OK, status) << "launchpad_go: " << error_message;
  info()->child.reset(child);
}

ProcessType MultiprocessExec::ChildProcess() {
  return info()->child.get();
}

}  // namespace test
}  // namespace crashpad
