// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "filesystem/path.h"

#include <windows.h>

#include <direct.h>
#include <errno.h>
#include <shellapi.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <algorithm>
#include <functional>
#include <list>
#include <memory>

namespace filesystem {
namespace {

size_t RootLength(const std::string& path) {
  if (path.size() == 0)
    return 0;
  if (path[0] == '/')
    return 1;
  if (path[0] == '\\') {
    if (path.size() < 2 || path[1] != '\\')
      return 1;
    // The path is a network share. Search for up to two '\'s, as they are
    // the server and share - and part of the root part.
    size_t index = path.find('\\', 2);
    if (index > 0) {
      index = path.find('\\', index + 1);
      if (index > 0)
        return index;
    }
    return path.size();
  }
  // If the path is of the form 'C:/' or 'C:\', with C being any letter, it's
  // a root part.
  if (path.length() >= 2 && path[1] == ':' &&
      (path[2] == '/' || path[2] == '\\') &&
      ((path[0] >= 'A' && path[0] <= 'Z') ||
       (path[0] >= 'a' && path[0] <= 'z'))) {
    return 3;
  }
  return 0;
}

size_t IsSeparator(const char sep) {
  return sep == '/' || sep == '\\';
}

size_t LastSeparator(const std::string& path) {
  return path.find_last_of("/\\");
}

size_t LastSeparator(const std::string& path, size_t pos) {
  return path.find_last_of("/\\", pos);
}

size_t FirstSeparator(const std::string& path, size_t pos) {
  return path.find_first_of("/\\", pos);
}

size_t ResolveParentDirectoryTraversal(const std::string& path,
                                       size_t put,
                                       size_t root_length) {
  if (put <= root_length) {
    return root_length;
  }
  size_t previous_separator = LastSeparator(path, put - 2);
  if (previous_separator != std::string::npos)
    return previous_separator + 1;
  return 0;
}
}  // namespace

std::string SimplifyPath(std::string path) {
  if (path.empty())
    return ".";

  size_t put = 0;
  size_t get = 0;
  size_t traversal_root = 0;
  size_t component_start = 0;

  size_t rootLength = RootLength(path);
  if (rootLength > 0) {
    put = rootLength;
    get = rootLength;
    component_start = rootLength;
  }

  while (get < path.size()) {
    char c = path[get];

    if (c == '.' && (get == component_start || get == component_start + 1)) {
      // We've seen "." or ".." so far in this component. We need to continue
      // searching.
      ++get;
      continue;
    }

    if (IsSeparator(c)) {
      if (get == component_start || get == component_start + 1) {
        // We've found a "/" or a "./", which we can elide.
        ++get;
        component_start = get;
        continue;
      }
      if (get == component_start + 2) {
        // We've found a "../", which means we need to remove the previous
        // component.
        if (put == traversal_root) {
          path[put++] = '.';
          path[put++] = '.';
          path[put++] = '\\';
          traversal_root = put;
        } else {
          put = ResolveParentDirectoryTraversal(path, put, rootLength);
        }
        ++get;
        component_start = get;
        continue;
      }
    }

    size_t next_separator = FirstSeparator(path, get);
    if (next_separator == std::string::npos) {
      // We've reached the last component.
      break;
    }
    size_t next_component_start = next_separator + 1;
    ++next_separator;
    size_t component_size = next_component_start - component_start;
    if (put != component_start && component_size > 0) {
      path.replace(put, component_size,
                   path.substr(component_start, component_size));
    }
    put += component_size;
    get = next_component_start;
    component_start = next_component_start;
  }

  size_t last_component_size = path.size() - component_start;
  if (last_component_size == 1 && path[component_start] == '.') {
    // The last component is ".", which we can elide.
  } else if (last_component_size == 2 && path[component_start] == '.' &&
             path[component_start + 1] == '.') {
    // The last component is "..", which means we need to remove the previous
    // component.
    if (put == traversal_root) {
      path[put++] = '.';
      path[put++] = '.';
      path[put++] = '\\';
      traversal_root = put;
    } else {
      put = ResolveParentDirectoryTraversal(path, put, rootLength);
    }
  } else {
    // Otherwise, we need to copy over the last component.
    if (put != component_start && last_component_size > 0) {
      path.replace(put, last_component_size,
                   path.substr(component_start, last_component_size));
    }
    put += last_component_size;
  }

  if (put >= 2 && IsSeparator(path[put - 1]))
    --put;  // Trim trailing /
  else if (put == 0)
    return ".";  // Use . for otherwise empty paths to treat them as relative.

  path.resize(put);
  std::replace(path.begin(), path.end(), '/', '\\');
  return path;
}

std::string AbsolutePath(const std::string& path) {
  char absPath[MAX_PATH];
  _fullpath(absPath, path.c_str(), MAX_PATH);
  return std::string(absPath);
}

std::string GetDirectoryName(const std::string& path) {
  size_t rootLength = RootLength(path);
  size_t separator = LastSeparator(path);
  if (separator < rootLength)
    separator = rootLength;
  if (separator == std::string::npos)
    return std::string();
  return path.substr(0, separator);
}

std::string GetBaseName(const std::string& path) {
  size_t separator = LastSeparator(path);
  if (separator == std::string::npos)
    return path;
  return path.substr(separator + 1);
}

std::string GetAbsoluteFilePath(const std::string& path) {
  HANDLE file =
      CreateFileA(path.c_str(), FILE_READ_ATTRIBUTES,
                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
                  OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  if (file == INVALID_HANDLE_VALUE) {
    return std::string();
  }
  char buffer[MAX_PATH];
  DWORD ret =
      GetFinalPathNameByHandleA(file, buffer, MAX_PATH, FILE_NAME_NORMALIZED);
  if (ret == 0 || ret > MAX_PATH) {
    CloseHandle(file);
    return std::string();
  }
  std::string result(buffer);
  result.erase(0, strlen("\\\\?\\"));
  CloseHandle(file);
  return result;
}

}  // namespace filesystem
