// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Shamelessly copied from the protobuf compiler's subprocess.cc
// except this version passes strings instead of Messages.

#include "upb_generator/subprocess.h"

#include <algorithm>
#include <cstring>
#include <iostream>

#ifndef _MSVC_LANG
#include <errno.h>
#include <signal.h>
#include <sys/select.h>
#include <sys/wait.h>
#endif

#include "absl/log/absl_log.h"
#include "absl/strings/substitute.h"

// Must be last.
#include "upb/port/def.inc"

namespace upb {
namespace generator {

namespace {
char* portable_strdup(const char* s) {
  char* ns = (char*)malloc(strlen(s) + 1);
  if (ns != nullptr) {
    strcpy(ns, s);
  }
  return ns;
}
}  // namespace

#ifdef _WIN32

static void CloseHandleOrDie(HANDLE handle) {
  if (!CloseHandle(handle)) {
    ABSL_LOG(FATAL) << "CloseHandle: "
                    << Subprocess::Win32ErrorMessage(GetLastError());
  }
}

Subprocess::Subprocess()
    : process_start_error_(ERROR_SUCCESS),
      child_handle_(nullptr),
      child_stdin_(nullptr),
      child_stdout_(nullptr) {}

Subprocess::~Subprocess() {
  if (child_stdin_ != nullptr) {
    CloseHandleOrDie(child_stdin_);
  }
  if (child_stdout_ != nullptr) {
    CloseHandleOrDie(child_stdout_);
  }
}

void Subprocess::Start(const std::string& program, SearchMode search_mode) {
  // Create the pipes.
  HANDLE stdin_pipe_read;
  HANDLE stdin_pipe_write;
  HANDLE stdout_pipe_read;
  HANDLE stdout_pipe_write;

  if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, nullptr, 0)) {
    ABSL_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError());
  }
  if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, nullptr, 0)) {
    ABSL_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError());
  }

  // Make child side of the pipes inheritable.
  if (!SetHandleInformation(stdin_pipe_read, HANDLE_FLAG_INHERIT,
                            HANDLE_FLAG_INHERIT)) {
    ABSL_LOG(FATAL) << "SetHandleInformation: "
                    << Win32ErrorMessage(GetLastError());
  }
  if (!SetHandleInformation(stdout_pipe_write, HANDLE_FLAG_INHERIT,
                            HANDLE_FLAG_INHERIT)) {
    ABSL_LOG(FATAL) << "SetHandleInformation: "
                    << Win32ErrorMessage(GetLastError());
  }

  // Setup STARTUPINFO to redirect handles.
  STARTUPINFOA startup_info;
  ZeroMemory(&startup_info, sizeof(startup_info));
  startup_info.cb = sizeof(startup_info);
  startup_info.dwFlags = STARTF_USESTDHANDLES;
  startup_info.hStdInput = stdin_pipe_read;
  startup_info.hStdOutput = stdout_pipe_write;
  startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);

  if (startup_info.hStdError == INVALID_HANDLE_VALUE) {
    ABSL_LOG(FATAL) << "GetStdHandle: " << Win32ErrorMessage(GetLastError());
  }

  // Invoking cmd.exe allows for '.bat' files from the path as well as '.exe'.
  // Using a malloc'ed string because CreateProcess() can mutate its second
  // parameter.
  char* command_line =
      portable_strdup(("cmd.exe /c \"" + program + "\"").c_str());

  // Create the process.
  PROCESS_INFORMATION process_info;

  if (CreateProcessA((search_mode == SEARCH_PATH) ? nullptr : program.c_str(),
                     (search_mode == SEARCH_PATH) ? command_line : nullptr,
                     nullptr,  // process security attributes
                     nullptr,  // thread security attributes
                     TRUE,     // inherit handles?
                     0,        // obscure creation flags
                     nullptr,  // environment (inherit from parent)
                     nullptr,  // current directory (inherit from parent)
                     &startup_info, &process_info)) {
    child_handle_ = process_info.hProcess;
    CloseHandleOrDie(process_info.hThread);
    child_stdin_ = stdin_pipe_write;
    child_stdout_ = stdout_pipe_read;
  } else {
    process_start_error_ = GetLastError();
    CloseHandleOrDie(stdin_pipe_write);
    CloseHandleOrDie(stdout_pipe_read);
  }

  CloseHandleOrDie(stdin_pipe_read);
  CloseHandleOrDie(stdout_pipe_write);
  free(command_line);
}

bool Subprocess::Communicate(const std::string& input_data,
                             std::string* output_data, std::string* error) {
  if (process_start_error_ != ERROR_SUCCESS) {
    *error = Win32ErrorMessage(process_start_error_);
    return false;
  }

  GOOGLE_CHECK(child_handle_ != nullptr) << "Must call Start() first.";

  int input_pos = 0;

  while (child_stdout_ != nullptr) {
    HANDLE handles[2];
    int handle_count = 0;

    if (child_stdin_ != nullptr) {
      handles[handle_count++] = child_stdin_;
    }
    if (child_stdout_ != nullptr) {
      handles[handle_count++] = child_stdout_;
    }

    DWORD wait_result =
        WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE);

    HANDLE signaled_handle = nullptr;
    if (wait_result >= WAIT_OBJECT_0 &&
        wait_result < WAIT_OBJECT_0 + handle_count) {
      signaled_handle = handles[wait_result - WAIT_OBJECT_0];
    } else if (wait_result == WAIT_FAILED) {
      ABSL_LOG(FATAL) << "WaitForMultipleObjects: "
                      << Win32ErrorMessage(GetLastError());
    } else {
      ABSL_LOG(FATAL) << "WaitForMultipleObjects: Unexpected return code: "
                      << wait_result;
    }

    if (signaled_handle == child_stdin_) {
      DWORD n;
      if (!WriteFile(child_stdin_, input_data.data() + input_pos,
                     input_data.size() - input_pos, &n, nullptr)) {
        // Child closed pipe.  Presumably it will report an error later.
        // Pretend we're done for now.
        input_pos = input_data.size();
      } else {
        input_pos += n;
      }

      if (input_pos == input_data.size()) {
        // We're done writing.  Close.
        CloseHandleOrDie(child_stdin_);
        child_stdin_ = nullptr;
      }
    } else if (signaled_handle == child_stdout_) {
      char buffer[4096];
      DWORD n;

      if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, nullptr)) {
        // We're done reading.  Close.
        CloseHandleOrDie(child_stdout_);
        child_stdout_ = nullptr;
      } else {
        output_data->append(buffer, n);
      }
    }
  }

  if (child_stdin_ != nullptr) {
    // Child did not finish reading input before it closed the output.
    // Presumably it exited with an error.
    CloseHandleOrDie(child_stdin_);
    child_stdin_ = nullptr;
  }

  DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE);

  if (wait_result == WAIT_FAILED) {
    ABSL_LOG(FATAL) << "WaitForSingleObject: "
                    << Win32ErrorMessage(GetLastError());
  } else if (wait_result != WAIT_OBJECT_0) {
    ABSL_LOG(FATAL) << "WaitForSingleObject: Unexpected return code: "
                    << wait_result;
  }

  DWORD exit_code;
  if (!GetExitCodeProcess(child_handle_, &exit_code)) {
    ABSL_LOG(FATAL) << "GetExitCodeProcess: "
                    << Win32ErrorMessage(GetLastError());
  }

  CloseHandleOrDie(child_handle_);
  child_handle_ = nullptr;

  if (exit_code != 0) {
    *error = absl::Substitute("Plugin failed with status code $0.", exit_code);
    return false;
  }

  return true;
}

std::string Subprocess::Win32ErrorMessage(DWORD error_code) {
  char* message;

  // WTF?
  FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
                     FORMAT_MESSAGE_IGNORE_INSERTS,
                 nullptr, error_code,
                 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
                 (LPSTR)&message,  // NOT A BUG!
                 0, nullptr);

  std::string result = message;
  LocalFree(message);
  return result;
}

// ===================================================================

#else  // _WIN32

Subprocess::Subprocess()
    : child_pid_(-1), child_stdin_(-1), child_stdout_(-1) {}

Subprocess::~Subprocess() {
  if (child_stdin_ != -1) {
    close(child_stdin_);
  }
  if (child_stdout_ != -1) {
    close(child_stdout_);
  }
}

void Subprocess::Start(const std::string& program, SearchMode search_mode) {
  // Note that we assume that there are no other threads, thus we don't have to
  // do crazy stuff like using socket pairs or avoiding libc locks.

  // [0] is read end, [1] is write end.
  int stdin_pipe[2];
  int stdout_pipe[2];

  int p0 = pipe(stdin_pipe);
  int p1 = pipe(stdout_pipe);
  UPB_ASSERT(p0 != -1);
  UPB_ASSERT(p1 != -1);

  char* argv[2] = {portable_strdup(program.c_str()), nullptr};

  child_pid_ = fork();
  if (child_pid_ == -1) {
    std::cerr << "fork: " << strerror(errno);
  } else if (child_pid_ == 0) {
    // We are the child.
    dup2(stdin_pipe[0], STDIN_FILENO);
    dup2(stdout_pipe[1], STDOUT_FILENO);

    close(stdin_pipe[0]);
    close(stdin_pipe[1]);
    close(stdout_pipe[0]);
    close(stdout_pipe[1]);

    switch (search_mode) {
      case SEARCH_PATH:
        execvp(argv[0], argv);
        break;
      case EXACT_NAME:
        execv(argv[0], argv);
        break;
    }

    // Write directly to STDERR_FILENO to avoid stdio code paths that may do
    // stuff that is unsafe here.
    int ignored;
    ignored = write(STDERR_FILENO, argv[0], strlen(argv[0]));
    const char* message =
        ": program not found or is not executable\n"
        "Please specify a program using absolute path or make sure "
        "the program is available in your PATH system variable\n";
    ignored = write(STDERR_FILENO, message, strlen(message));
    (void)ignored;

    // Must use _exit() rather than exit() to avoid flushing output buffers
    // that will also be flushed by the parent.
    _exit(1);
  } else {
    free(argv[0]);

    close(stdin_pipe[0]);
    close(stdout_pipe[1]);

    child_stdin_ = stdin_pipe[1];
    child_stdout_ = stdout_pipe[0];
  }
}

bool Subprocess::Communicate(const std::string& input_data,
                             std::string* output_data, std::string* error) {
  if (child_stdin_ == -1) {
    std::cerr << "Must call Start() first." << '\n';
    UPB_ASSERT(child_stdin_ != -1);
  }

  // The "sighandler_t" typedef is GNU-specific, so define our own.
  typedef void SignalHandler(int);

  // Make sure SIGPIPE is disabled so that if the child dies it doesn't kill us.
  SignalHandler* old_pipe_handler = signal(SIGPIPE, SIG_IGN);

  int input_pos = 0;
  int max_fd = std::max(child_stdin_, child_stdout_);

  while (child_stdout_ != -1) {
    fd_set read_fds;
    fd_set write_fds;
    FD_ZERO(&read_fds);
    FD_ZERO(&write_fds);
    if (child_stdout_ != -1) {
      FD_SET(child_stdout_, &read_fds);
    }
    if (child_stdin_ != -1) {
      FD_SET(child_stdin_, &write_fds);
    }

    if (select(max_fd + 1, &read_fds, &write_fds, nullptr, nullptr) < 0) {
      if (errno == EINTR) {
        // Interrupted by signal.  Try again.
        continue;
      } else {
        std::cerr << "select: " << strerror(errno) << '\n';
        UPB_ASSERT(0);
      }
    }

    if (child_stdin_ != -1 && FD_ISSET(child_stdin_, &write_fds)) {
      int n = write(child_stdin_, input_data.data() + input_pos,
                    input_data.size() - input_pos);
      if (n < 0) {
        // Child closed pipe.  Presumably it will report an error later.
        // Pretend we're done for now.
        input_pos = input_data.size();
      } else {
        input_pos += n;
      }

      if (input_pos == (int)input_data.size()) {
        // We're done writing.  Close.
        close(child_stdin_);
        child_stdin_ = -1;
      }
    }

    if (child_stdout_ != -1 && FD_ISSET(child_stdout_, &read_fds)) {
      char buffer[4096];
      int n = read(child_stdout_, buffer, sizeof(buffer));

      if (n > 0) {
        output_data->append(buffer, (size_t)n);
      } else {
        // We're done reading.  Close.
        close(child_stdout_);
        child_stdout_ = -1;
      }
    }
  }

  if (child_stdin_ != -1) {
    // Child did not finish reading input before it closed the output.
    // Presumably it exited with an error.
    close(child_stdin_);
    child_stdin_ = -1;
  }

  int status;
  while (waitpid(child_pid_, &status, 0) == -1) {
    if (errno != EINTR) {
      std::cerr << "waitpid: " << strerror(errno) << '\n';
      UPB_ASSERT(0);
    }
  }

  // Restore SIGPIPE handling.
  signal(SIGPIPE, old_pipe_handler);

  if (WIFEXITED(status)) {
    if (WEXITSTATUS(status) != 0) {
      int error_code = WEXITSTATUS(status);
      *error =
          absl::Substitute("Plugin failed with status code $0.", error_code);
      return false;
    }
  } else if (WIFSIGNALED(status)) {
    int signal = WTERMSIG(status);
    *error = absl::Substitute("Plugin killed by signal $0.", signal);
    return false;
  } else {
    *error = "Neither WEXITSTATUS nor WTERMSIG is true?";
    return false;
  }

  return true;
}

#endif  // !_WIN32

}  // namespace generator
}  // namespace upb
