// Copyright 2017 The Bazel 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.

// For rand_s function, https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx
#define _CRT_RAND_S
#include <fcntl.h>
#include <io.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <algorithm>
#include <sstream>
#include <string>

#include "src/main/cpp/util/path_platform.h"
#include "src/tools/launcher/util/launcher_util.h"

namespace bazel {
namespace launcher {

using std::string;
using std::stringstream;
using std::wostringstream;
using std::wstring;

string GetLastErrorString() {
  DWORD last_error = GetLastError();
  if (last_error == 0) {
    return string();
  }

  char* message_buffer;
  size_t size = FormatMessageA(
      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
          FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL, last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPSTR)&message_buffer, 0, NULL);

  stringstream result;
  result << "(error: " << last_error << "): " << message_buffer;
  LocalFree(message_buffer);
  return result.str();
}

void die(const wchar_t* format, ...) {
  // Set translation mode to _O_U8TEXT so that we can display
  // error message containing unicode correctly.
  _setmode(_fileno(stderr), _O_U8TEXT);
  va_list ap;
  va_start(ap, format);
  fputws(L"LAUNCHER ERROR: ", stderr);
  vfwprintf(stderr, format, ap);
  va_end(ap);
  fputwc(L'\n', stderr);
  exit(1);
}

void PrintError(const wchar_t* format, ...) {
  // Set translation mode to _O_U8TEXT so that we can display
  // error message containing unicode correctly.
  // _setmode returns -1 if it fails to set the mode.
  int previous_mode = _setmode(_fileno(stderr), _O_U8TEXT);
  va_list ap;
  va_start(ap, format);
  fputws(L"LAUNCHER ERROR: ", stderr);
  vfwprintf(stderr, format, ap);
  va_end(ap);
  fputwc(L'\n', stderr);
  // Set translation mode back to the original one if it's changed.
  if (previous_mode != -1) {
    _setmode(_fileno(stderr), previous_mode);
  }
}

wstring AsAbsoluteWindowsPath(const wchar_t* path) {
  wstring wpath;
  string error;
  if (!blaze_util::AsAbsoluteWindowsPath(path, &wpath, &error)) {
    die(L"Couldn't convert %s to absolute Windows path: %hs", path,
        error.c_str());
  }
  return wpath;
}

bool DoesFilePathExist(const wchar_t* path) {
  DWORD dwAttrib = GetFileAttributesW(AsAbsoluteWindowsPath(path).c_str());

  return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
          !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

bool DoesDirectoryPathExist(const wchar_t* path) {
  DWORD dwAttrib = GetFileAttributesW(AsAbsoluteWindowsPath(path).c_str());

  return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
          (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

bool DeleteFileByPath(const wchar_t* path) {
  return DeleteFileW(AsAbsoluteWindowsPath(path).c_str());
}

bool DeleteDirectoryByPath(const wchar_t* path) {
  return RemoveDirectoryW(AsAbsoluteWindowsPath(path).c_str());
}

wstring GetBinaryPathWithoutExtension(const wstring& binary) {
  if (binary.find(L".exe", binary.size() - 4) != wstring::npos) {
    return binary.substr(0, binary.length() - 4);
  }
  return binary;
}

wstring GetBinaryPathWithExtension(const wstring& binary) {
  return GetBinaryPathWithoutExtension(binary) + L".exe";
}

static wstring GetEscapedArgument(const wstring& argument,
                                  bool escape_backslash) {
  wstring escaped_arg;
  // escaped_arg will be at least this long
  escaped_arg.reserve(argument.size());
  bool has_space = argument.find_first_of(L' ') != wstring::npos;

  if (argument.empty()) {
    return L"\"\"";
  }

  if (has_space) {
    escaped_arg += L'\"';
  }

  for (const wchar_t ch : argument) {
    switch (ch) {
      case L'"':
        // Escape double quotes
        escaped_arg += L"\\\"";
        break;

      case L'\\':
        // Escape back slashes if escape_backslash is true
        escaped_arg += (escape_backslash ? L"\\\\" : L"\\");
        break;

      default:
        escaped_arg += ch;
    }
  }

  if (has_space) {
    escaped_arg += L'\"';
  }
  return escaped_arg;
}

std::wstring BashEscapeArg(const std::wstring& arg) {
  return GetEscapedArgument(arg, /* escape_backslash */ true);
}

// Escape arguments for CreateProcessW.
//
// This algorithm is based on information found in
// http://daviddeley.com/autohotkey/parameters/parameters.htm
//
// The following source specifies a similar algorithm:
// https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/
// unfortunately I found this algorithm only after creating the one below, but
// fortunately they seem to do the same.
std::wstring WindowsEscapeArg2(const std::wstring& s) {
  if (s.empty()) {
    return L"\"\"";
  } else {
    bool needs_escaping = false;
    for (const auto& c : s) {
      if (c == ' ' || c == '"') {
        needs_escaping = true;
        break;
      }
    }
    if (!needs_escaping) {
      return s;
    }
  }

  std::wostringstream result;
  result << L'"';
  int start = 0;
  for (int i = 0; i < s.size(); ++i) {
    char c = s[i];
    if (c == '"' || c == '\\') {
      // Copy the segment since the last special character.
      if (start >= 0) {
        result << s.substr(start, i - start);
        start = -1;
      }

      // Handle the current special character.
      if (c == '"') {
        // This is a quote character. Escape it with a single backslash.
        result << L"\\\"";
      } else {
        // This is a backslash (or the first one in a run of backslashes).
        // Whether we escape it depends on whether the run ends with a quote.
        int run_len = 1;
        int j = i + 1;
        while (j < s.size() && s[j] == '\\') {
          run_len++;
          j++;
        }
        if (j == s.size()) {
          // The run of backslashes goes to the end.
          // We have to escape every backslash with another backslash.
          for (int k = 0; k < run_len * 2; ++k) {
            result << L'\\';
          }
          break;
        } else if (j < s.size() && s[j] == '"') {
          // The run of backslashes is terminated by a quote.
          // We have to escape every backslash with another backslash, and
          // escape the quote with one backslash.
          for (int k = 0; k < run_len * 2; ++k) {
            result << L'\\';
          }
          result << L"\\\"";
          i += run_len;  // 'i' is also increased in the loop iteration step
        } else {
          // No quote found. Each backslash counts for itself, they must not be
          // escaped.
          for (int k = 0; k < run_len; ++k) {
            result << L'\\';
          }
          i += run_len - 1;  // 'i' is also increased in the loop iteration step
        }
      }
    } else {
      // This is not a special character. Start the segment if necessary.
      if (start < 0) {
        start = i;
      }
    }
  }
  // Save final segment after the last special character.
  if (start != -1) {
    result << s.substr(start);
  }
  result << L'"';
  return result.str();
}

std::wstring WindowsEscapeArg(const std::wstring& arg) {
  // TODO(laszlocsomor): use WindowsEscapeArg2 instead.
  return GetEscapedArgument(arg, /* escape_backslash */ false);
}

// An environment variable has a maximum size limit of 32,767 characters
// https://msdn.microsoft.com/en-us/library/ms683188.aspx
static const int BUFFER_SIZE = 32767;

bool GetEnv(const wstring& env_name, wstring* value) {
  wchar_t buffer[BUFFER_SIZE];
  if (!GetEnvironmentVariableW(env_name.c_str(), buffer, BUFFER_SIZE)) {
    return false;
  }
  *value = buffer;
  return true;
}

bool SetEnv(const wstring& env_name, const wstring& value) {
  return SetEnvironmentVariableW(env_name.c_str(), value.c_str());
}

wstring GetRandomStr(size_t len) {
  static const wchar_t alphabet[] =
      L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  wstring rand_str;
  rand_str.reserve(len);
  unsigned int x;
  for (size_t i = 0; i < len; i++) {
    rand_s(&x);
    rand_str += alphabet[x % wcslen(alphabet)];
  }
  return rand_str;
}

bool NormalizePath(const wstring& path, wstring* result) {
  string error;
  if (!blaze_util::AsWindowsPath(path, result, &error)) {
    PrintError(L"Failed to normalize %s: %hs", path.c_str(), error.c_str());
    return false;
  }
  std::transform(result->begin(), result->end(), result->begin(), ::tolower);
  return true;
}

wstring GetBaseNameFromPath(const wstring& path) {
  return path.substr(path.find_last_of(L"\\/") + 1);
}

wstring GetParentDirFromPath(const wstring& path) {
  return path.substr(0, path.find_last_of(L"\\/"));
}

bool RelativeTo(const wstring& path, const wstring& base, wstring* result) {
  if (blaze_util::IsAbsolute(path) != blaze_util::IsAbsolute(base)) {
    PrintError(
        L"Cannot calculate relative path from an absolute and a non-absolute"
        " path.\npath = %s\nbase = %s",
        path.c_str(), base.c_str());
    return false;
  }

  if (blaze_util::IsAbsolute(path) && blaze_util::IsAbsolute(base) &&
      path[0] != base[0]) {
    PrintError(
        L"Cannot calculate relative path from absolute path under different "
        "drives."
        "\npath = %s\nbase = %s",
        path.c_str(), base.c_str());
    return false;
  }

  // Record the back slash position after the last matched path fragment
  int pos = 0;
  int back_slash_pos = -1;
  while (path[pos] == base[pos] && base[pos] != L'\0') {
    if (path[pos] == L'\\') {
      back_slash_pos = pos;
    }
    pos++;
  }

  if (base[pos] == L'\0' && path[pos] == L'\0') {
    // base == path in this case
    result->assign(L"");
    return true;
  }

  if ((base[pos] == L'\0' && path[pos] == L'\\') ||
      (base[pos] == L'\\' && path[pos] == L'\0')) {
    // In this case, one of the paths is the parent of another one.
    // We should move back_slash_pos to the end of the shorter path.
    // eg. path = c:\foo\bar, base = c:\foo => back_slash_pos = 6
    //  or path = c:\foo, base = c:\foo\bar => back_slash_pos = 6
    back_slash_pos = pos;
  }

  wostringstream buffer;

  // Create the ..\\ prefix
  // eg. path = C:\foo\bar1, base = C:\foo\bar2, we need ..\ prefix
  // In case "base" is a parent of "path", we set back_slash_pos to the end
  // of "base", so we need no prefix when back_slash_pos + 1 > base.length().
  // back_slash_pos + 1 == base.length() is not possible because the last
  // character of a normalized path won't be back slash.
  if (back_slash_pos + 1 < base.length()) {
    buffer << L"..\\";
  }
  for (int i = back_slash_pos + 1; i < base.length(); i++) {
    if (base[i] == L'\\') {
      buffer << L"..\\";
    }
  }

  // Add the result of not matched path fragments into result
  // eg. path = C:\foo\bar1, base = C:\foo\bar2, adding `bar1`
  // In case "path" is a parent of "base", we set back_slash_pos to the end
  // of "path", so we need no suffix when back_slash_pos == path.length().
  if (back_slash_pos != path.length()) {
    buffer << path.substr(back_slash_pos + 1);
  }

  result->assign(buffer.str());
  return true;
}

}  // namespace launcher
}  // namespace bazel
