// 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:
  static bool Create(HANDLE stdin_h, HANDLE stdout_h, HANDLE stderr_h,
                     std::unique_ptr<AutoAttributeList>* result,
                     wstring* error_msg = nullptr);
  ~AutoAttributeList();

  void InitStartupInfoExA(STARTUPINFOEXA* startup_info) const;

  void InitStartupInfoExW(STARTUPINFOEXW* startup_info) const;

 private:
  struct StdHandles {
    static constexpr size_t kHandleCount = 3;
    union {
      HANDLE handle_array[kHandleCount];
      struct {
        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__
