//===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides the Win32 specific implementation of the Program class.
//
//===----------------------------------------------------------------------===//

#include "Windows.h"
#include <cstdio>
#include <malloc.h>
#include <io.h>
#include <fcntl.h>

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only Win32 specific code
//===          and must not be UNIX code
//===----------------------------------------------------------------------===//

namespace {
  struct Win32ProcessInfo {
    HANDLE hProcess;
    DWORD  dwProcessId;
  };
}

namespace llvm {
using namespace sys;

Program::Program() : Data_(0) {}

Program::~Program() {
  if (Data_) {
    Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
    CloseHandle(wpi->hProcess);
    delete wpi;
    Data_ = 0;
  }
}

unsigned Program::GetPid() const {
  Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
  return wpi->dwProcessId;
}

// This function just uses the PATH environment variable to find the program.
Path
Program::FindProgramByName(const std::string& progName) {

  // Check some degenerate cases
  if (progName.length() == 0) // no program
    return Path();
  Path temp;
  if (!temp.set(progName)) // invalid name
    return Path();
  // Return paths with slashes verbatim.
  if (progName.find('\\') != std::string::npos ||
      progName.find('/') != std::string::npos)
    return temp;

  // At this point, the file name is valid and does not contain slashes.
  // Let Windows search for it.
  char buffer[MAX_PATH];
  char *dummy = NULL;
  DWORD len = SearchPath(NULL, progName.c_str(), ".exe", MAX_PATH,
                         buffer, &dummy);

  // See if it wasn't found.
  if (len == 0)
    return Path();

  // See if we got the entire path.
  if (len < MAX_PATH)
    return Path(buffer);

  // Buffer was too small; grow and retry.
  while (true) {
    char *b = reinterpret_cast<char *>(_alloca(len+1));
    DWORD len2 = SearchPath(NULL, progName.c_str(), ".exe", len+1, b, &dummy);

    // It is unlikely the search failed, but it's always possible some file
    // was added or removed since the last search, so be paranoid...
    if (len2 == 0)
      return Path();
    else if (len2 <= len)
      return Path(b);

    len = len2;
  }
}

static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) {
  HANDLE h;
  if (path == 0) {
    DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
                    GetCurrentProcess(), &h,
                    0, TRUE, DUPLICATE_SAME_ACCESS);
    return h;
  }

  const char *fname;
  if (path->isEmpty())
    fname = "NUL";
  else
    fname = path->c_str();

  SECURITY_ATTRIBUTES sa;
  sa.nLength = sizeof(sa);
  sa.lpSecurityDescriptor = 0;
  sa.bInheritHandle = TRUE;

  h = CreateFile(fname, fd ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ,
                 &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
                 FILE_ATTRIBUTE_NORMAL, NULL);
  if (h == INVALID_HANDLE_VALUE) {
    MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
        (fd ? "input: " : "output: "));
  }

  return h;
}

/// ArgNeedsQuotes - Check whether argument needs to be quoted when calling
/// CreateProcess.
static bool ArgNeedsQuotes(const char *Str) {
  return Str[0] == '\0' || strpbrk(Str, "\t \"&\'()*<>\\`^|") != 0;
}


/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
/// CreateProcess and returns length of quoted arg with escaped quotes
static unsigned int ArgLenWithQuotes(const char *Str) {
  unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0;

  while (*Str != '\0') {
    if (*Str == '\"')
      ++len;

    ++len;
    ++Str;
  }

  return len;
}


bool
Program::Execute(const Path& path,
                 const char** args,
                 const char** envp,
                 const Path** redirects,
                 unsigned memoryLimit,
                 std::string* ErrMsg) {
  if (Data_) {
    Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
    CloseHandle(wpi->hProcess);
    delete wpi;
    Data_ = 0;
  }

  if (!path.canExecute()) {
    if (ErrMsg)
      *ErrMsg = "program not executable";
    return false;
  }

  // Windows wants a command line, not an array of args, to pass to the new
  // process.  We have to concatenate them all, while quoting the args that
  // have embedded spaces (or are empty).

  // First, determine the length of the command line.
  unsigned len = 0;
  for (unsigned i = 0; args[i]; i++) {
    len += ArgLenWithQuotes(args[i]) + 1;
  }

  // Now build the command line.
  char *command = reinterpret_cast<char *>(_alloca(len+1));
  char *p = command;

  for (unsigned i = 0; args[i]; i++) {
    const char *arg = args[i];

    bool needsQuoting = ArgNeedsQuotes(arg);
    if (needsQuoting)
      *p++ = '"';

    while (*arg != '\0') {
      if (*arg == '\"')
        *p++ = '\\';

      *p++ = *arg++;
    }

    if (needsQuoting)
      *p++ = '"';
    *p++ = ' ';
  }

  *p = 0;

  // The pointer to the environment block for the new process.
  char *envblock = 0;

  if (envp) {
    // An environment block consists of a null-terminated block of
    // null-terminated strings. Convert the array of environment variables to
    // an environment block by concatenating them.

    // First, determine the length of the environment block.
    len = 0;
    for (unsigned i = 0; envp[i]; i++)
      len += strlen(envp[i]) + 1;

    // Now build the environment block.
    envblock = reinterpret_cast<char *>(_alloca(len+1));
    p = envblock;

    for (unsigned i = 0; envp[i]; i++) {
      const char *ev = envp[i];
      size_t len = strlen(ev) + 1;
      memcpy(p, ev, len);
      p += len;
    }

    *p = 0;
  }

  // Create a child process.
  STARTUPINFO si;
  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  si.hStdInput = INVALID_HANDLE_VALUE;
  si.hStdOutput = INVALID_HANDLE_VALUE;
  si.hStdError = INVALID_HANDLE_VALUE;

  if (redirects) {
    si.dwFlags = STARTF_USESTDHANDLES;

    si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg);
    if (si.hStdInput == INVALID_HANDLE_VALUE) {
      MakeErrMsg(ErrMsg, "can't redirect stdin");
      return false;
    }
    si.hStdOutput = RedirectIO(redirects[1], 1, ErrMsg);
    if (si.hStdOutput == INVALID_HANDLE_VALUE) {
      CloseHandle(si.hStdInput);
      MakeErrMsg(ErrMsg, "can't redirect stdout");
      return false;
    }
    if (redirects[1] && redirects[2] && *(redirects[1]) == *(redirects[2])) {
      // If stdout and stderr should go to the same place, redirect stderr
      // to the handle already open for stdout.
      DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
                      GetCurrentProcess(), &si.hStdError,
                      0, TRUE, DUPLICATE_SAME_ACCESS);
    } else {
      // Just redirect stderr
      si.hStdError = RedirectIO(redirects[2], 2, ErrMsg);
      if (si.hStdError == INVALID_HANDLE_VALUE) {
        CloseHandle(si.hStdInput);
        CloseHandle(si.hStdOutput);
        MakeErrMsg(ErrMsg, "can't redirect stderr");
        return false;
      }
    }
  }

  PROCESS_INFORMATION pi;
  memset(&pi, 0, sizeof(pi));

  fflush(stdout);
  fflush(stderr);
  BOOL rc = CreateProcess(path.c_str(), command, NULL, NULL, TRUE, 0,
                          envblock, NULL, &si, &pi);
  DWORD err = GetLastError();

  // Regardless of whether the process got created or not, we are done with
  // the handles we created for it to inherit.
  CloseHandle(si.hStdInput);
  CloseHandle(si.hStdOutput);
  CloseHandle(si.hStdError);

  // Now return an error if the process didn't get created.
  if (!rc) {
    SetLastError(err);
    MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") +
               path.str() + "'");
    return false;
  }
  Win32ProcessInfo* wpi = new Win32ProcessInfo;
  wpi->hProcess = pi.hProcess;
  wpi->dwProcessId = pi.dwProcessId;
  Data_ = wpi;

  // Make sure these get closed no matter what.
  AutoHandle hThread(pi.hThread);

  // Assign the process to a job if a memory limit is defined.
  AutoHandle hJob(0);
  if (memoryLimit != 0) {
    hJob = CreateJobObject(0, 0);
    bool success = false;
    if (hJob != 0) {
      JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
      memset(&jeli, 0, sizeof(jeli));
      jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
      jeli.ProcessMemoryLimit = uintptr_t(memoryLimit) * 1048576;
      if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation,
                                  &jeli, sizeof(jeli))) {
        if (AssignProcessToJobObject(hJob, pi.hProcess))
          success = true;
      }
    }
    if (!success) {
      SetLastError(GetLastError());
      MakeErrMsg(ErrMsg, std::string("Unable to set memory limit"));
      TerminateProcess(pi.hProcess, 1);
      WaitForSingleObject(pi.hProcess, INFINITE);
      return false;
    }
  }

  return true;
}

int
Program::Wait(const Path &path,
              unsigned secondsToWait,
              std::string* ErrMsg) {
  if (Data_ == 0) {
    MakeErrMsg(ErrMsg, "Process not started!");
    return -1;
  }

  Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
  HANDLE hProcess = wpi->hProcess;

  // Wait for the process to terminate.
  DWORD millisecondsToWait = INFINITE;
  if (secondsToWait > 0)
    millisecondsToWait = secondsToWait * 1000;

  if (WaitForSingleObject(hProcess, millisecondsToWait) == WAIT_TIMEOUT) {
    if (!TerminateProcess(hProcess, 1)) {
      MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
      // -2 indicates a crash or timeout as opposed to failure to execute.
      return -2;
    }
    WaitForSingleObject(hProcess, INFINITE);
  }

  // Get its exit status.
  DWORD status;
  BOOL rc = GetExitCodeProcess(hProcess, &status);
  DWORD err = GetLastError();

  if (!rc) {
    SetLastError(err);
    MakeErrMsg(ErrMsg, "Failed getting status for program.");
    // -2 indicates a crash or timeout as opposed to failure to execute.
    return -2;
  }

  return status;
}

bool
Program::Kill(std::string* ErrMsg) {
  if (Data_ == 0) {
    MakeErrMsg(ErrMsg, "Process not started!");
    return true;
  }

  Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
  HANDLE hProcess = wpi->hProcess;
  if (TerminateProcess(hProcess, 1) == 0) {
    MakeErrMsg(ErrMsg, "The process couldn't be killed!");
    return true;
  }

  return false;
}

bool Program::ChangeStdinToBinary(){
  int result = _setmode( _fileno(stdin), _O_BINARY );
  return result == -1;
}

bool Program::ChangeStdoutToBinary(){
  int result = _setmode( _fileno(stdout), _O_BINARY );
  return result == -1;
}

bool Program::ChangeStderrToBinary(){
  int result = _setmode( _fileno(stderr), _O_BINARY );
  return result == -1;
}

}
