// Copyright 2015 The Crashpad Authors
//
// 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 <sys/types.h>

#include "base/check.h"
#include "base/strings/utf_string_conversions.h"
#include "gtest/gtest.h"
#include "util/win/command_line.h"

namespace crashpad {
namespace test {

namespace internal {

struct MultiprocessInfo {
  MultiprocessInfo() {}
  ScopedFileHANDLE pipe_c2p_read;
  ScopedFileHANDLE pipe_c2p_write;
  ScopedFileHANDLE pipe_p2c_read;
  ScopedFileHANDLE pipe_p2c_write;
  PROCESS_INFORMATION process_info;
};

}  // 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();

  // Reap the child.
  WaitForSingleObject(info_->process_info.hProcess, INFINITE);
  CloseHandle(info_->process_info.hThread);
  CloseHandle(info_->process_info.hProcess);
}

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

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

FileHandle Multiprocess::ReadPipeHandle() const {
  // This is the parent case, it's stdin in the child.
  return info_->pipe_c2p_read.get();
}

FileHandle Multiprocess::WritePipeHandle() const {
  // This is the parent case, it's stdout in the child.
  return info_->pipe_p2c_write.get();
}

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

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

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

  info_->pipe_c2p_read.reset();
  info_->pipe_p2c_write.reset();
}

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

  info_->pipe_c2p_write.reset();
  info_->pipe_p2c_read.reset();
}

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

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());

  command_line_.clear();
  AppendCommandLineArgument(command_.value(), &command_line_);
  for (size_t i = 0; i < arguments_.size(); ++i) {
    AppendCommandLineArgument(base::UTF8ToWide(arguments_[i]), &command_line_);
  }

  // Make pipes for child-to-parent and parent-to-child communication. Mark them
  // as inheritable via the SECURITY_ATTRIBUTES, but use SetHandleInformation to
  // ensure that the parent sides are not inherited.
  ASSERT_EQ(info(), nullptr);
  set_info(new internal::MultiprocessInfo());

  SECURITY_ATTRIBUTES security_attributes = {0};
  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  security_attributes.bInheritHandle = TRUE;

  HANDLE c2p_read, c2p_write;
  PCHECK(CreatePipe(&c2p_read, &c2p_write, &security_attributes, 0));
  PCHECK(SetHandleInformation(c2p_read, HANDLE_FLAG_INHERIT, 0));
  info()->pipe_c2p_read.reset(c2p_read);
  info()->pipe_c2p_write.reset(c2p_write);

  HANDLE p2c_read, p2c_write;
  PCHECK(CreatePipe(&p2c_read, &p2c_write, &security_attributes, 0));
  PCHECK(SetHandleInformation(p2c_write, HANDLE_FLAG_INHERIT, 0));
  info()->pipe_p2c_read.reset(p2c_read);
  info()->pipe_p2c_write.reset(p2c_write);
}

void MultiprocessExec::MultiprocessChild() {
  STARTUPINFO startup_info = {0};
  startup_info.cb = sizeof(startup_info);
  startup_info.hStdInput = info()->pipe_p2c_read.get();
  startup_info.hStdOutput = info()->pipe_c2p_write.get();
  startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
  startup_info.dwFlags = STARTF_USESTDHANDLES;
  PCHECK(CreateProcess(command_.value().c_str(),
                       &command_line_[0],  // This cannot be constant, per MSDN.
                       nullptr,
                       nullptr,
                       TRUE,
                       0,
                       nullptr,
                       nullptr,
                       &startup_info,
                       &info()->process_info));
}

ProcessType MultiprocessExec::ChildProcess() {
  return info()->process_info.hProcess;
}

}  // namespace test
}  // namespace crashpad
