// Copyright 2016 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.

#ifndef BAZEL_SRC_MAIN_NATIVE_WINDOWS_UTIL_H__
#define BAZEL_SRC_MAIN_NATIVE_WINDOWS_UTIL_H__

#include <windows.h>

#include <memory>
#include <string>

namespace bazel {
namespace windows {

using std::wstring;

// A wrapper for the `HANDLE` type that calls CloseHandle in its d'tor.
// WARNING: do not use for HANDLE returned by FindFirstFile; those must be
// closed with FindClose (otherwise they aren't closed properly).
class AutoHandle {
 public:
  explicit AutoHandle(HANDLE handle = INVALID_HANDLE_VALUE) : handle_(handle) {}
  AutoHandle(const AutoHandle&) = delete;
  AutoHandle(AutoHandle&& other) = delete;
  AutoHandle& operator=(const AutoHandle&) = delete;
  AutoHandle& operator=(AutoHandle&& other) = delete;

  ~AutoHandle() {
    if (IsValid()) {
      ::CloseHandle(handle_);
    }
  }

  AutoHandle(AutoHandle* other) : handle_(other->handle_) {
    other->handle_ = INVALID_HANDLE_VALUE;
  }

  bool IsValid() const {
    return handle_ != INVALID_HANDLE_VALUE && handle_ != NULL;
  }

  AutoHandle& operator=(const HANDLE& rhs) {
    if (IsValid()) {
      ::CloseHandle(handle_);
    }
    handle_ = rhs;
    return *this;
  }

  operator HANDLE() const { return handle_; }

 private:
  HANDLE handle_;
};

class AutoAttributeList {
 public:
  AutoAttributeList() {}

  static bool Create(HANDLE stdin_h, HANDLE stdout_h, HANDLE stderr_h,
                     std::unique_ptr<AutoAttributeList>* result,
                     std::wstring* error_msg = nullptr);
  ~AutoAttributeList();

  bool InheritAnyHandles() const { return handles_.ValidHandlesCount() > 0; }

  void InitStartupInfoExW(STARTUPINFOEXW* startup_info) const;

 private:
  class StdHandles {
   public:
    StdHandles();
    StdHandles(HANDLE stdin_h, HANDLE stdout_h, HANDLE stderr_h);
    size_t ValidHandlesCount() const { return valid_handles_; }
    HANDLE* ValidHandles() { return valid_handle_array_; }
    HANDLE StdIn() const { return stdin_h_; }
    HANDLE StdOut() const { return stdout_h_; }
    HANDLE StdErr() const { return stderr_h_; }

   private:
    size_t valid_handles_;
    HANDLE valid_handle_array_[3];
    HANDLE stdin_h_;
    HANDLE stdout_h_;
    HANDLE stderr_h_;
  };

  AutoAttributeList(std::unique_ptr<uint8_t[]>&& data, HANDLE stdin_h,
                    HANDLE stdout_h, HANDLE stderr_h);
  AutoAttributeList(const AutoAttributeList&) = delete;
  AutoAttributeList& operator=(const AutoAttributeList&) = delete;

  operator LPPROC_THREAD_ATTRIBUTE_LIST() const;

  std::unique_ptr<uint8_t[]> data_;
  StdHandles handles_;
};

#define WSTR1(x) L##x
#define WSTR(x) WSTR1(x)

wstring MakeErrorMessage(const wchar_t* file, int line,
                         const wchar_t* failed_func, const wstring& func_arg,
                         const wstring& message);
wstring MakeErrorMessage(const wchar_t* file, int line,
                         const wchar_t* failed_func, const wstring& func_arg,
                         DWORD error_code);
wstring GetLastErrorString(DWORD error_code);

// Same as `AsExecutablePathForCreateProcess` except it won't quote the result.
wstring AsShortPath(wstring path, wstring* result);

// Computes a path suitable as the executable part in CreateProcessA's cmdline.
//
// The null-terminated executable path for CreateProcessA has to fit into
// MAX_PATH, therefore the limit for the executable's path is MAX_PATH - 1
// (not including null terminator). This method attempts to convert the input
// `path` to a short format to fit it into the MAX_PATH - 1 limit.
//
// `path` must be either an absolute, normalized, Windows-style path with drive
// letter (e.g. "c:\foo\bar.exe", but no "\foo\bar.exe"), or must be just a file
// name (e.g. "cmd.exe") that's shorter than MAX_PATH (without null-terminator).
// In both cases, `path` must be unquoted.
//
// If this function succeeds, it returns an empty string (indicating no error),
// and sets `result` to the resulting path, which is always quoted, and is
// always at most MAX_PATH + 1 long (MAX_PATH - 1 without null terminator, plus
// two quotes). If there's any error, this function returns the error message.
//
// If `path` is at most MAX_PATH - 1 long (not including null terminator), the
// result will be that (plus quotes).
// Otherwise this method attempts to compute an 8dot3 style short name for
// `path`, and if that succeeds and the result is at most MAX_PATH - 1 long (not
// including null terminator), then that will be the result (plus quotes).
// Otherwise this function fails and returns an error message.
wstring AsExecutablePathForCreateProcess(const wstring& path, wstring* result);

}  // namespace windows
}  // namespace bazel

#endif  // BAZEL_SRC_MAIN_NATIVE_WINDOWS_UTIL_H__
