// Copyright 2015 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 <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::UTF8ToUTF16(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
