/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmPathResolver.h"

#include <algorithm>
#include <cerrno>
#include <cstddef>
#include <string>
#include <utility>

#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>

#ifdef _WIN32
#  include <windows.h>

#  include <cmsys/String.h>
#endif

#define MAX_SYMBOLIC_LINKS 32

namespace cm {
namespace PathResolver {

namespace {

namespace Options {

enum class ActualCase
{
  No,
  Yes,
};

enum class Symlinks
{
  None,
  Lazy,
  Eager,
};

enum class Existence
{
  Agnostic,
  Required,
};
}

enum class Root
{
  None,
  POSIX,
#ifdef _WIN32
  Drive,
  Network,
#endif
};

struct Control
{
  enum class Tag
  {
    Continue,
    Restart,
    Error,
  };
  Tag tag;
  union
  {
    std::string::size_type slash; // data for Continue
    cmsys::Status error;          // data for Error
  };
  static Control Continue(std::string::size_type s)
  {
    Control c{ Tag::Continue };
    c.slash = s;
    return c;
  }
  static Control Restart() { return Control{ Tag::Restart }; }
  static Control Error(cmsys::Status e)
  {
    Control c{ Tag::Error };
    c.error = e;
    return c;
  }

private:
  Control(Tag t)
    : tag(t)
  {
  }
};

Root ClassifyRoot(cm::string_view p)
{
#ifdef _WIN32
  if (p.size() >= 2 && cmsysString_isalpha(p[0]) && p[1] == ':') {
    return Root::Drive;
  }
  if (p.size() >= 3 && p[0] == '/' && p[1] == '/' && p[2] != '/') {
    return Root::Network;
  }
#endif
  if (!p.empty() && p[0] == '/') {
    return Root::POSIX;
  }
  return Root::None;
}

class ImplBase
{
protected:
  ImplBase(System& os)
    : OS(os)
  {
  }

  System& OS;
  std::string P;
  std::size_t SymlinkDepth = 0;

#ifdef _WIN32
  std::string GetWorkingDirectoryOnDrive(char letter);
  Control ResolveRootRelative();
#endif
  cm::optional<std::string> ReadSymlink(std::string const& path,
                                        cmsys::Status& status);
  Control ResolveSymlink(Root root, std::string::size_type slash,
                         std::string::size_type next_slash,
                         std::string symlink_target);
};

template <class Policy>
class Impl : public ImplBase
{
  Control ResolveRelativePath();
  Control ResolveRoot(Root root);
  Control ResolveComponent(Root root, std::string::size_type root_slash,
                           std::string::size_type slash);
  Control ResolvePath();

public:
  Impl(System& os)
    : ImplBase(os)
  {
  }
  cmsys::Status Resolve(std::string in, std::string& out);
};

template <class Policy>
Control Impl<Policy>::ResolveRelativePath()
{
  // This is a relative path.  Convert it to absolute and restart.
  std::string p = this->OS.GetWorkingDirectory();
  std::replace(p.begin(), p.end(), '\\', '/');
  if (ClassifyRoot(p) == Root::None) {
    p.insert(0, 1, '/');
  }
  if (p.back() != '/') {
    p.push_back('/');
  }
  P.insert(0, p);
  return Control::Restart();
}

#ifdef _WIN32
std::string ImplBase::GetWorkingDirectoryOnDrive(char letter)
{
  // Use the drive's working directory, if any.
  std::string d = this->OS.GetWorkingDirectoryOnDrive(letter);
  std::replace(d.begin(), d.end(), '\\', '/');
  if (d.size() >= 3 &&
      cmsysString_toupper(d[0]) == cmsysString_toupper(letter) &&
      d[1] == ':' && d[2] == '/') {
    d[0] = letter;
    d.push_back('/');
    return d;
  }

  // Use the current working directory if the drive matches.
  d = this->OS.GetWorkingDirectory();
  if (d.size() >= 3 &&
      cmsysString_toupper(d[0]) == cmsysString_toupper(letter) &&
      d[1] == ':' && d[2] == '/') {
    d[0] = letter;
    d.push_back('/');
    return d;
  }

  // Fall back to the root directory on the drive.
  d = "_:/";
  d[0] = letter;
  return d;
}

Control ImplBase::ResolveRootRelative()
{
  // This is a root-relative path.  Resolve the root drive and restart.
  P.replace(0, 2, this->GetWorkingDirectoryOnDrive(P[0]));
  return Control::Restart();
}
#endif

cm::optional<std::string> ImplBase::ReadSymlink(std::string const& path,
                                                cmsys::Status& status)
{
  cm::optional<std::string> result;
  std::string target;
  status = this->OS.ReadSymlink(path, target);
  if (status && ++this->SymlinkDepth >= MAX_SYMBOLIC_LINKS) {
    status = cmsys::Status::POSIX(ELOOP);
  }
  if (status) {
    if (!target.empty()) {
      result = std::move(target);
    }
  } else if (status.GetPOSIX() == EINVAL
#ifdef _WIN32
             || status.GetWindows() == ERROR_NOT_A_REPARSE_POINT
#endif
  ) {
    // The path was not a symlink.
    status = cmsys::Status::Success();
  }
  return result;
}

Control ImplBase::ResolveSymlink(Root root, std::string::size_type slash,
                                 std::string::size_type next_slash,
                                 std::string symlink_target)
{
  std::replace(symlink_target.begin(), symlink_target.end(), '\\', '/');
  Root const symlink_target_root = ClassifyRoot(symlink_target);
  if (symlink_target_root == Root::None) {
    // This is a symlink to a relative path.
    // Resolve the symlink, while preserving the leading and
    // trailing (if any) slash:
    //   "*/link/" => "*/dest/"
    //     ^slash       ^slash
    P.replace(slash + 1, next_slash - slash - 1, symlink_target);
    return Control::Continue(slash);
  }

#ifdef _WIN32
  if (root == Root::Drive && symlink_target_root == Root::POSIX) {
    // This is a symlink to a POSIX absolute path,
    // but the current path is on a drive letter.  Resolve the
    // symlink while preserving the drive letter, and start over:
    //   "C:/*/link/" => "C:/dest/"
    //        ^slash      (restart)
    P.replace(2, next_slash - 2, symlink_target);
    return Control::Restart();
  }
#else
  static_cast<void>(root);
#endif

  // This is a symlink to an absolute path.
  // Resolve it and start over:
  //   "*/link/" => "/dest/"
  //     ^slash      (restart)
  P.replace(0, next_slash, symlink_target);
  return Control::Restart();
}

template <class Policy>
Control Impl<Policy>::ResolveRoot(Root root)
{
  if (root == Root::None) {
    return this->ResolveRelativePath();
  }

  // POSIX absolute paths always start with a '/'.
  std::string::size_type root_slash = 0;

#ifdef _WIN32
  if (root == Root::Drive) {
    if (P.size() == 2 || P[2] != '/') {
      return this->ResolveRootRelative();
    }

    if (Policy::ActualCase == Options::ActualCase::Yes) {
      // Normalize the drive letter to upper-case.
      P[0] = static_cast<char>(cmsysString_toupper(P[0]));
    }

    // The root is a drive letter.  The root '/' immediately follows.
    root_slash = 2;
  } else if (root == Root::Network) {
    // The root is a network name.  Find the root '/' after it.
    root_slash = P.find('/', 2);
    if (root_slash == std::string::npos) {
      root_slash = P.size();
      P.push_back('/');
    }
  }
#endif

  if (Policy::Existence == Options::Existence::Required
#ifdef _WIN32
      && root != Root::Network
#endif
  ) {
    std::string path = P.substr(0, root_slash + 1);
    if (!this->OS.PathExists(path)) {
      P = std::move(path);
      return Control::Error(cmsys::Status::POSIX(ENOENT));
    }
  }

  return Control::Continue(root_slash);
}

template <class Policy>
Control Impl<Policy>::ResolveComponent(Root root,
                                       std::string::size_type root_slash,
                                       std::string::size_type slash)
{
  // Look for the '/' or end-of-input that ends this component.
  // The sample paths in comments below show the trailing slash
  // even if it is actually beyond the end of the path.
  std::string::size_type next_slash = P.find('/', slash + 1);
  if (next_slash == std::string::npos) {
    next_slash = P.size();
  }
  cm::string_view c =
    cm::string_view(P).substr(slash + 1, next_slash - (slash + 1));

  if (slash == root_slash) {
    if (c.empty() || c == "."_s || c == ".."_s) {
      // This is an empty, '.', or '..' component at the root.
      // Drop the component and its trailing slash, if any,
      // while preserving the root slash:
      //   "//"   => "/"
      //   "/./"  => "/"
      //   "/../" => "/"
      //    ^slash    ^slash
      P.erase(slash + 1, next_slash - slash);
      return Control::Continue(slash);
    }
  } else {
    if (c.empty() || c == "."_s) {
      // This is an empty or '.' component not at the root.
      // Drop the component and its leading slash:
      //   "*//"  => "*/"
      //   "*/./" => "*/"
      //     ^slash    ^slash
      P.erase(slash, next_slash - slash);
      return Control::Continue(slash);
    }

    if (c == ".."_s) {
      // This is a '..' component not at the root.
      // Rewind to the previous component:
      //   "*/prev/../" => "*/prev/../"
      //          ^slash     ^slash
      next_slash = slash;
      slash = P.rfind('/', slash - 1);

      if (Policy::Symlinks == Options::Symlinks::Lazy) {
        cmsys::Status status;
        std::string path = P.substr(0, next_slash);
        if (cm::optional<std::string> maybe_symlink_target =
              this->ReadSymlink(path, status)) {
          return this->ResolveSymlink(root, slash, next_slash,
                                      std::move(*maybe_symlink_target));
        }
        if (!status && Policy::Existence == Options::Existence::Required) {
          P = std::move(path);
          return Control::Error(status);
        }
      }

      // This is not a symlink.
      // Drop the component, the following '..', and its trailing slash,
      // if any, while preserving the (possibly root) leading slash:
      //   "*/dir/../" => "*/"
      //     ^slash         ^slash
      P.erase(slash + 1, next_slash + 3 - slash);
      return Control::Continue(slash);
    }
  }

  // This is a named component.

  if (Policy::Symlinks == Options::Symlinks::Eager) {
    cmsys::Status status;
    std::string path = P.substr(0, next_slash);
    if (cm::optional<std::string> maybe_symlink_target =
          this->ReadSymlink(path, status)) {
      return this->ResolveSymlink(root, slash, next_slash,
                                  std::move(*maybe_symlink_target));
    }
    if (!status && Policy::Existence == Options::Existence::Required) {
      P = std::move(path);
      return Control::Error(status);
    }
  }

#if defined(_WIN32) || defined(__APPLE__)
  bool exists = false;
  if (Policy::ActualCase == Options::ActualCase::Yes) {
    std::string name;
    std::string path = P.substr(0, next_slash);
    if (cmsys::Status status = this->OS.ReadName(path, name)) {
      exists = true;
      if (!name.empty()) {
        // Rename this component:
        //   "*/name/" => "*/Name/"
        //     ^slash       ^slash
        P.replace(slash + 1, next_slash - slash - 1, name);
        next_slash = slash + 1 + name.length();
      }
    } else if (Policy::Existence == Options::Existence::Required) {
      P = std::move(path);
      return Control::Error(status);
    }
  }
#endif

  if (Policy::Existence == Options::Existence::Required
#if defined(_WIN32) || defined(__APPLE__)
      && !exists
#endif
  ) {
    std::string path = P.substr(0, next_slash);
    if (!this->OS.PathExists(path)) {
      P = std::move(path);
      return Control::Error(cmsys::Status::POSIX(ENOENT));
    }
  }

  // Keep this component:
  //   "*/name/" => "*/name/"
  //     ^slash            ^slash
  return Control::Continue(next_slash);
}

template <class Policy>
Control Impl<Policy>::ResolvePath()
{
  Root const root = ClassifyRoot(P);

  // Resolve the root component.  It always ends in a slash.
  Control control = this->ResolveRoot(root);
  if (control.tag != Control::Tag::Continue) {
    return control;
  }
  std::string::size_type const root_slash = control.slash;

  // Resolve later components.  Every iteration that finishes
  // the loop body makes progress either by removing a component
  // or advancing the slash past it.
  for (std::string::size_type slash = root_slash;
       P.size() > root_slash + 1 && slash < P.size();) {
    control = this->ResolveComponent(root, root_slash, slash);
    if (control.tag != Control::Tag::Continue) {
      return control;
    }
    slash = control.slash;
  }
  return Control::Continue(P.size());
}

template <class Policy>
cmsys::Status Impl<Policy>::Resolve(std::string in, std::string& out)
{
  P = std::move(in);
  std::replace(P.begin(), P.end(), '\\', '/');
  for (;;) {
    Control control = this->ResolvePath();
    switch (control.tag) {
      case Control::Tag::Continue:
        out = std::move(P);
        return cmsys::Status::Success();
      case Control::Tag::Restart:
        continue;
      case Control::Tag::Error:
        out = std::move(P);
        return control.error;
    };
  }
}

}

namespace Policies {
struct NaivePath
{
#if defined(_WIN32) || defined(__APPLE__)
  static constexpr Options::ActualCase ActualCase = Options::ActualCase::No;
#endif
  static constexpr Options::Symlinks Symlinks = Options::Symlinks::None;
  static constexpr Options::Existence Existence = Options::Existence::Agnostic;
};
struct CasePath
{
#if defined(_WIN32) || defined(__APPLE__)
  static constexpr Options::ActualCase ActualCase = Options::ActualCase::Yes;
#endif
  static constexpr Options::Symlinks Symlinks = Options::Symlinks::None;
  static constexpr Options::Existence Existence = Options::Existence::Agnostic;
};
struct RealPath
{
#if defined(_WIN32) || defined(__APPLE__)
  static constexpr Options::ActualCase ActualCase = Options::ActualCase::Yes;
#endif
  static constexpr Options::Symlinks Symlinks = Options::Symlinks::Eager;
  static constexpr Options::Existence Existence = Options::Existence::Required;
};
struct LogicalPath
{
#if defined(_WIN32) || defined(__APPLE__)
  static constexpr Options::ActualCase ActualCase = Options::ActualCase::Yes;
#endif
  static constexpr Options::Symlinks Symlinks = Options::Symlinks::Lazy;
  static constexpr Options::Existence Existence = Options::Existence::Agnostic;
};

#if defined(__SUNPRO_CC)
constexpr Options::Symlinks NaivePath::Symlinks;
constexpr Options::Existence NaivePath::Existence;
constexpr Options::Symlinks CasePath::Symlinks;
constexpr Options::Existence CasePath::Existence;
constexpr Options::Symlinks RealPath::Symlinks;
constexpr Options::Existence RealPath::Existence;
constexpr Options::Symlinks LogicalPath::Symlinks;
constexpr Options::Existence LogicalPath::Existence;
#endif
}

template <class Policy>
Resolver<Policy>::Resolver(System& os)
  : OS(os)
{
}
template <class Policy>
cmsys::Status Resolver<Policy>::Resolve(std::string in, std::string& out) const
{
  return Impl<Policy>(OS).Resolve(std::move(in), out);
}

System::System() = default;
System::~System() = default;

template class Resolver<Policies::LogicalPath>;
template class Resolver<Policies::RealPath>;
template class Resolver<Policies::CasePath>;
template class Resolver<Policies::NaivePath>;

}
}
