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

#include <windows.h>

#include <memory>
#include <sstream>
#include <string>

#include "src/main/native/windows_file_operations.h"
#include "src/main/native/windows_util.h"

namespace windows_util {

using std::string;
using std::unique_ptr;
using std::wstring;

int IsJunctionOrDirectorySymlink(const WCHAR* path) {
  DWORD attrs = ::GetFileAttributesW(path);
  if (attrs == INVALID_FILE_ATTRIBUTES) {
    return IS_JUNCTION_ERROR;
  } else {
    if ((attrs & FILE_ATTRIBUTE_DIRECTORY) &&
        (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) {
      return IS_JUNCTION_YES;
    } else {
      return IS_JUNCTION_NO;
    }
  }
}

bool GetLongPath(const WCHAR* path, unique_ptr<WCHAR[]>* result) {
  DWORD size = ::GetLongPathNameW(path, NULL, 0);
  if (size == 0) {
    return false;
  }
  result->reset(new WCHAR[size]);
  ::GetLongPathNameW(path, result->get(), size);
  return true;
}

HANDLE OpenDirectory(const WCHAR* path, bool read_write) {
  return ::CreateFileW(
      /* lpFileName */ path,
      /* dwDesiredAccess */
      read_write ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_READ,
      /* dwShareMode */ 0,
      /* lpSecurityAttributes */ NULL,
      /* dwCreationDisposition */ OPEN_EXISTING,
      /* dwFlagsAndAttributes */ FILE_FLAG_OPEN_REPARSE_POINT |
          FILE_FLAG_BACKUP_SEMANTICS,
      /* hTemplateFile */ NULL);
}

#pragma pack(push, 4)
typedef struct _JunctionDescription {
  typedef struct _Header {
    DWORD ReparseTag;
    WORD ReparseDataLength;
    WORD Reserved;
  } Header;

  typedef struct _WriteDesc {
    WORD SubstituteNameOffset;
    WORD SubstituteNameLength;
    WORD PrintNameOffset;
    WORD PrintNameLength;
  } WriteDesc;

  Header header;
  WriteDesc write;
  WCHAR PathBuffer[ANYSIZE_ARRAY];
} JunctionDescription;
#pragma pack(pop)

string CreateJunction(const wstring& junction_name,
                      const wstring& junction_target) {
  const wstring target = HasUncPrefix(junction_target.c_str())
                             ? junction_target.substr(4)
                             : junction_target;
  // The entire JunctionDescription cannot be larger than
  // MAXIMUM_REPARSE_DATA_BUFFER_SIZE bytes.
  //
  // The structure's layout is:
  //   [JunctionDescription::Header]
  //   [JunctionDescription::WriteDesc]
  //   ---- start of JunctionDescription::PathBuffer ----
  //   [4 WCHARs]             : "\??\" prefix
  //   [target.size() WCHARs] : junction target name
  //   [1 WCHAR]              : null-terminator
  //   [target.size() WCHARs] : junction target displayed name
  //   [1 WCHAR]              : null-terminator
  // The sum of these must not exceed MAXIMUM_REPARSE_DATA_BUFFER_SIZE.
  // We can rearrange this to get the limit for target.size().
  static const size_t kMaxJunctionTargetLen =
      ((MAXIMUM_REPARSE_DATA_BUFFER_SIZE - sizeof(JunctionDescription::Header) -
        sizeof(JunctionDescription::WriteDesc) -
        /* one "\??\" prefix */ sizeof(WCHAR) * 4 -
        /* two null terminators */ sizeof(WCHAR) * 2) /
       /* two copies of the string are stored */ 2) /
      sizeof(WCHAR);
  if (target.size() > kMaxJunctionTargetLen) {
    std::stringstream error;
    error << "junction target is too long (" << target.size()
          << " characters, limit: " << kMaxJunctionTargetLen << ")";
    return error.str();
  }
  const wstring name = HasUncPrefix(junction_name.c_str())
                           ? junction_name
                           : (wstring(L"\\\\?\\") + junction_name);

  // Junctions are directories, so create one
  if (!::CreateDirectoryW(name.c_str(), NULL)) {
    return string("CreateDirectoryW failed");
  }

  AutoHandle handle(OpenDirectory(name.c_str(), true));
  if (!handle.IsValid()) {
    return string("OpenDirectory failed");
  }

  char reparse_buffer_bytes[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
  JunctionDescription* reparse_buffer =
      reinterpret_cast<JunctionDescription*>(reparse_buffer_bytes);
  memset(reparse_buffer_bytes, 0, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);

  // "\??\" is meaningful to the kernel, it's a synomym for the "\DosDevices\"
  // object path. (NOT to be confused with "\\?\" which is meaningful for the
  // Win32 API.) We need to use this prefix to tell the kernel where the reparse
  // point is pointing to.
  memcpy(reparse_buffer->PathBuffer, L"\\??\\", 4 * sizeof(WCHAR));
  memcpy(reparse_buffer->PathBuffer + 4, target.c_str(),
         target.size() * sizeof(WCHAR));

  // In addition to their target, junctions also have another string which is a
  // user-visible name of where the junction points, as listed by "dir". This
  // can be any string and won't affect the usability of the junction.
  // MKLINK uses the target path without the "\??\" prefix as the display name,
  // so let's do that here too. This is also in line with how UNIX behaves.
  // Using a dummy or fake display name would be pure evil, it would make the
  // output of `dir` look like:
  //   2017-01-18  01:37 PM    <JUNCTION>     juncname [dummy string]
  memcpy(reparse_buffer->PathBuffer + 4 + target.size() + 1, target.c_str(),
         target.size() * sizeof(WCHAR));

  reparse_buffer->write.SubstituteNameOffset = 0;
  reparse_buffer->write.SubstituteNameLength =
      (4 + target.size()) * sizeof(WCHAR);
  reparse_buffer->write.PrintNameOffset =
      reparse_buffer->write.SubstituteNameLength +
      /* null-terminator */ sizeof(WCHAR);
  reparse_buffer->write.PrintNameLength = target.size() * sizeof(WCHAR);

  reparse_buffer->header.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
  reparse_buffer->header.ReparseDataLength =
      sizeof(JunctionDescription::WriteDesc) +
      reparse_buffer->write.SubstituteNameLength +
      reparse_buffer->write.PrintNameLength +
      /* 2 null-terminators */ (2 * sizeof(WCHAR));
  reparse_buffer->header.Reserved = 0;

  DWORD bytes_returned;
  if (!::DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, reparse_buffer,
                         reparse_buffer->header.ReparseDataLength +
                             sizeof(JunctionDescription::Header),
                         NULL, 0, &bytes_returned, NULL)) {
    return string("DeviceIoControl(FSCTL_SET_REPARSE_POINT) failed");
  }
  return "";
}

}  // namespace windows_util
