/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */

#pragma once

#include "cmConfigure.h" // IWYU pragma: keep

#include <cstddef>
#include <string>
#include <utility>

#include <cm/filesystem>
#include <cm/string_view>
#include <cm/type_traits>
#include <cmext/string_view>

namespace detail {
#if defined(__SUNPRO_CC) && defined(__sparc)
// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
// the full 'is_pathable' and 'is_move_pathable' checks.  We use it only to
// improve error messages via 'enable_if' when calling methods with incorrect
// types. Just pretend all types are allowed so we can at least compile valid
// code.
template <typename T>
struct is_pathable : std::true_type
{
};

template <typename T>
struct is_move_pathable : std::true_type
{
};

#else
template <typename T, typename = void>
struct is_pathable : std::false_type
{
};

template <>
struct is_pathable<cm::filesystem::path> : std::true_type
{
};
template <>
struct is_pathable<std::string> : std::true_type
{
};
template <>
struct is_pathable<cm::string_view> : std::true_type
{
};
template <>
struct is_pathable<cm::static_string_view> : std::true_type
{
};
template <typename T>
struct is_pathable<
  T,
  cm::enable_if_t<std::is_same<char*, typename std::decay<T>::type>::value,
                  void>>
  : cm::bool_constant<std::is_same<char*, typename std::decay<T>::type>::value>
{
};

template <typename T>
struct is_move_pathable : std::false_type
{
};

template <>
struct is_move_pathable<cm::filesystem::path> : std::true_type
{
};
template <>
struct is_move_pathable<std::string> : std::true_type
{
};
#endif
}

class cmCMakePath
{
private:
  template <typename Source>
  using enable_if_move_pathable =
    cm::enable_if_t<detail::is_move_pathable<Source>::value, cmCMakePath&>;

  template <typename Source>
  using enable_if_pathable =
    cm::enable_if_t<detail::is_pathable<Source>::value, cmCMakePath&>;

public:
  using value_type = cm::filesystem::path::value_type;
  using string_type = cm::filesystem::path::string_type;

  enum format : unsigned char
  {
    auto_format =
      static_cast<unsigned char>(cm::filesystem::path::format::auto_format),
    native_format =
      static_cast<unsigned char>(cm::filesystem::path::format::native_format),
    generic_format =
      static_cast<unsigned char>(cm::filesystem::path::format::generic_format)
  };

  class iterator;
  using const_iterator = iterator;

  cmCMakePath() noexcept = default;

  cmCMakePath(const cmCMakePath&) = default;

  cmCMakePath(cmCMakePath&& path) noexcept
    : Path(std::forward<cm::filesystem::path>(path.Path))
  {
  }

  cmCMakePath(cm::filesystem::path path) noexcept
    : Path(std::move(path))
  {
  }
  cmCMakePath(cm::string_view source, format fmt = generic_format) noexcept
    : Path(FormatPath(source, fmt))
  {
  }
  template <typename Source, typename = enable_if_move_pathable<Source>>
  cmCMakePath(Source source, format fmt = generic_format)
    : Path(FormatPath(std::move(source), fmt))
  {
  }

  template <typename Source, typename = enable_if_move_pathable<Source>>
  cmCMakePath& Assign(Source&& source)
  {
    this->Path = std::forward<Source>(source);
    return *this;
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& Assign(const Source& source)
  {
    this->Path = source;
    return *this;
  }

  cmCMakePath& operator=(const cmCMakePath& path)
  {
    if (this != &path) {
      this->Path = path.Path;
    }
    return *this;
  }
  cmCMakePath& operator=(cmCMakePath&& path) noexcept
  {
    if (this != &path) {
      this->Path = std::move(path.Path);
    }
    return *this;
  }
  template <typename Source, typename = enable_if_move_pathable<Source>>
  cmCMakePath& operator=(Source&& source)
  {
    this->Assign(std::forward<Source>(source));
    return *this;
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& operator=(const Source& source)
  {
    this->Assign(source);
    return *this;
  }

  // Concatenation
  cmCMakePath& Append(const cmCMakePath& path)
  {
    return this->Append(path.Path);
  }
  cmCMakePath& Append(const cm::filesystem::path& path)
  {
    this->Path /= path;
    // filesystem::path::append use preferred_separator ('\' on Windows)
    // so convert back to '/'
    this->Path = this->Path.generic_string();
    return *this;
  }

  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& Append(const Source& source)
  {
    return this->Append(cm::filesystem::path(source));
  }

  cmCMakePath& operator/=(const cmCMakePath& path)
  {
    return this->Append(path);
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& operator/=(const Source& source)
  {
    return this->Append(source);
  }

  cmCMakePath& Concat(const cmCMakePath& path)
  {
    this->Path += path.Path;
    return *this;
  }
  cmCMakePath& Concat(cm::static_string_view source)
  {
    this->Path.concat(std::string(source));
    return *this;
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& Concat(const Source& source)
  {
    this->Path.concat(source);
    return *this;
  }

  cmCMakePath& operator+=(const cmCMakePath& path)
  {
    return this->Concat(path);
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& operator+=(const Source& source)
  {
    return this->Concat(source);
  }

  // Manipulation
  void Clear() noexcept { this->Path.clear(); }

  cmCMakePath& RemoveFileName()
  {
    this->Path.remove_filename();
    return *this;
  }

  cmCMakePath& ReplaceFileName(const cmCMakePath& filename)
  {
    if (this->Path.has_filename()) {
      this->Path.replace_filename(filename.Path);
    }
    return *this;
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& ReplaceFileName(const Source& filename)
  {
    if (this->Path.has_filename()) {
      this->Path.replace_filename(filename);
    }
    return *this;
  }

  cmCMakePath& ReplaceExtension(const cmCMakePath& extension = cmCMakePath())
  {
    this->Path.replace_extension(extension.Path);
    return *this;
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& ReplaceExtension(const Source& extension)
  {
    this->Path.replace_extension(extension);
    return *this;
  }

  cmCMakePath& ReplaceWideExtension(
    const cmCMakePath& extension = cmCMakePath())
  {
    return this->ReplaceWideExtension(
      static_cast<cm::string_view>(extension.Path.string()));
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath& ReplaceWideExtension(const Source& extension)
  {
    return this->ReplaceWideExtension(cm::string_view(extension));
  }
  cmCMakePath& ReplaceWideExtension(cm::string_view extension);

  cmCMakePath& RemoveExtension()
  {
    if (this->Path.has_extension()) {
      this->ReplaceExtension(cm::string_view(""));
    }
    return *this;
  }

  cmCMakePath& RemoveWideExtension()
  {
    if (this->Path.has_extension()) {
      this->ReplaceWideExtension(cm::string_view(""));
    }
    return *this;
  }

  void swap(cmCMakePath& other) noexcept { this->Path.swap(other.Path); }

  // Observers
  std::string String() const { return this->Path.string(); }
  std::wstring WString() const { return this->Path.wstring(); }

  string_type Native() const
  {
    string_type path;
    this->GetNativePath(path);

    return path;
  }
  std::string NativeString() const
  {
    std::string path;
    this->GetNativePath(path);

    return path;
  }
  std::wstring NativeWString() const
  {
    std::wstring path;
    this->GetNativePath(path);

    return path;
  }
  std::string GenericString() const { return this->Path.generic_string(); }
  std::wstring GenericWString() const { return this->Path.generic_wstring(); }

  // Decomposition
  cmCMakePath GetRootName() const { return this->Path.root_name(); }
  cmCMakePath GetRootDirectory() const { return this->Path.root_directory(); }
  cmCMakePath GetRootPath() const { return this->Path.root_path(); }
  cmCMakePath GetFileName() const { return this->Path.filename(); }
  cmCMakePath GetExtension() const { return this->Path.extension(); }
  cmCMakePath GetWideExtension() const;
  cmCMakePath GetStem() const { return this->Path.stem(); }
  cmCMakePath GetNarrowStem() const;

  cmCMakePath GetRelativePath() const { return this->Path.relative_path(); }
  cmCMakePath GetParentPath() const { return this->Path.parent_path(); }

  // Generation
  cmCMakePath Normal() const
  {
    auto path = this->Path.lexically_normal();
    // filesystem::path:lexically_normal use preferred_separator ('\') on
    // Windows) so convert back to '/'
    return path.generic_string();
  }

  cmCMakePath Relative(const cmCMakePath& base) const
  {
    return this->Relative(base.Path);
  }
  cmCMakePath Relative(const cm::filesystem::path& base) const
  {
    auto path = this->Path.lexically_relative(base);
    // filesystem::path:lexically_relative use preferred_separator ('\') on
    // Windows) so convert back to '/'
    return path.generic_string();
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath Relative(const Source& base) const
  {
    return this->Relative(cm::filesystem::path(base));
  }

  cmCMakePath Proximate(const cmCMakePath& base) const
  {
    return this->Proximate(base.Path);
  }
  cmCMakePath Proximate(const cm::filesystem::path& base) const
  {
    auto path = this->Path.lexically_proximate(base);
    // filesystem::path::lexically_proximate use preferred_separator ('\') on
    // Windows) so convert back to '/'
    return path.generic_string();
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath Proximate(const Source& base) const
  {
    return this->Proximate(cm::filesystem::path(base));
  }

  cmCMakePath Absolute(const cmCMakePath& base) const
  {
    return this->Absolute(base.Path);
  }
  template <typename Source, typename = enable_if_pathable<Source>>
  cmCMakePath Absolute(const Source& base) const
  {
    return this->Absolute(cm::filesystem::path(base));
  }
  cmCMakePath Absolute(const cm::filesystem::path& base) const;

  // Comparison
  int Compare(const cmCMakePath& path) const noexcept
  {
    return this->Path.compare(path.Path);
  }

  // Query
  bool IsEmpty() const noexcept { return this->Path.empty(); }

  bool HasRootPath() const { return this->Path.has_root_path(); }
  bool HasRootName() const { return this->Path.has_root_name(); }
  bool HasRootDirectory() const { return this->Path.has_root_directory(); }
  bool HasRelativePath() const { return this->Path.has_relative_path(); }
  bool HasParentPath() const { return this->Path.has_parent_path(); }
  bool HasFileName() const { return this->Path.has_filename(); }
  bool HasStem() const { return this->Path.has_stem(); }
  bool HasExtension() const { return this->Path.has_extension(); }

  bool IsAbsolute() const { return this->Path.is_absolute(); }
  bool IsRelative() const { return this->Path.is_relative(); }
  bool IsPrefix(const cmCMakePath& path) const;

  // Iterators
  // =========
  inline iterator begin() const;
  inline iterator end() const;

  // Non-members
  // ===========
  friend inline bool operator==(const cmCMakePath& lhs,
                                const cmCMakePath& rhs) noexcept
  {
    return lhs.Compare(rhs) == 0;
  }
  friend inline bool operator!=(const cmCMakePath& lhs,
                                const cmCMakePath& rhs) noexcept
  {
    return lhs.Compare(rhs) != 0;
  }

  friend inline cmCMakePath operator/(const cmCMakePath& lhs,
                                      const cmCMakePath& rhs)
  {
    cmCMakePath result(lhs);
    result /= rhs;

    return result;
  }

private:
  friend std::size_t hash_value(const cmCMakePath& path) noexcept;

  static std::string FormatPath(std::string path, format fmt = generic_format);
  static std::string FormatPath(cm::string_view path,
                                format fmt = generic_format)
  {
    return FormatPath(std::string(path), fmt);
  }

  void GetNativePath(std::string& path) const;
  void GetNativePath(std::wstring& path) const;

  cm::filesystem::path Path;
};

class cmCMakePath::iterator
{
public:
  using iterator_category = cm::filesystem::path::iterator::iterator_category;

  using value_type = cmCMakePath;
  using difference_type = cm::filesystem::path::iterator::difference_type;
  using pointer = const cmCMakePath*;
  using reference = const cmCMakePath&;

  iterator() = default;

  iterator(const iterator& other)
    : Iterator(other.Iterator)
    , Path(other.Path)
    , PathElement(*this->Iterator)
  {
  }

  ~iterator() = default;

  iterator& operator=(const iterator& other)
  {
    if (this != &other) {
      this->Iterator = other.Iterator;
      this->Path = other.Path;
      this->PathElement = *this->Iterator;
    }

    return *this;
  }

  reference operator*() const { return this->PathElement; }

  pointer operator->() const { return &this->PathElement; }

  iterator& operator++()
  {
    ++this->Iterator;
    this->PathElement = *this->Iterator;

    return *this;
  }

  iterator operator++(int)
  {
    iterator it(*this);
    this->operator++();
    return it;
  }

  iterator& operator--()
  {
    --this->Iterator;
    this->PathElement = *this->Iterator;

    return *this;
  }

  iterator operator--(int)
  {
    iterator it(*this);
    this->operator--();
    return it;
  }

private:
  friend class cmCMakePath;
  friend bool operator==(const iterator&, const iterator&);

  iterator(const cmCMakePath* path, const cm::filesystem::path::iterator& it)
    : Iterator(it)
    , Path(path)
    , PathElement(*this->Iterator)
  {
  }

  cm::filesystem::path::iterator Iterator;
  const cmCMakePath* Path = nullptr;
  cmCMakePath PathElement;
};

inline cmCMakePath::iterator cmCMakePath::begin() const
{
  return iterator(this, this->Path.begin());
}
inline cmCMakePath::iterator cmCMakePath::end() const
{
  return iterator(this, this->Path.end());
}

// Non-member functions
// ====================
inline bool operator==(const cmCMakePath::iterator& lhs,
                       const cmCMakePath::iterator& rhs)
{
  return lhs.Path == rhs.Path && lhs.Path != nullptr &&
    lhs.Iterator == rhs.Iterator;
}

inline bool operator!=(const cmCMakePath::iterator& lhs,
                       const cmCMakePath::iterator& rhs)
{
  return !(lhs == rhs);
}

inline void swap(cmCMakePath& lhs, cmCMakePath& rhs) noexcept
{
  lhs.swap(rhs);
}

inline std::size_t hash_value(const cmCMakePath& path) noexcept
{
  return cm::filesystem::hash_value(path.Path);
}
