//===-- FileSpec.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"

#include <algorithm>
#include <optional>
#include <system_error>
#include <vector>

#include <cassert>
#include <climits>
#include <cstdio>
#include <cstring>

using namespace lldb;
using namespace lldb_private;

namespace {

static constexpr FileSpec::Style GetNativeStyle() {
#if defined(_WIN32)
  return FileSpec::Style::windows;
#else
  return FileSpec::Style::posix;
#endif
}

bool PathStyleIsPosix(FileSpec::Style style) {
  return llvm::sys::path::is_style_posix(style);
}

const char *GetPathSeparators(FileSpec::Style style) {
  return llvm::sys::path::get_separator(style).data();
}

char GetPreferredPathSeparator(FileSpec::Style style) {
  return GetPathSeparators(style)[0];
}

void Denormalize(llvm::SmallVectorImpl<char> &path, FileSpec::Style style) {
  if (PathStyleIsPosix(style))
    return;

  llvm::replace(path, '/', '\\');
}

} // end anonymous namespace

FileSpec::FileSpec() : m_style(GetNativeStyle()) {}

// Default constructor that can take an optional full path to a file on disk.
FileSpec::FileSpec(llvm::StringRef path, Style style) : m_style(style) {
  SetFile(path, style);
}

FileSpec::FileSpec(llvm::StringRef path, const llvm::Triple &triple)
    : FileSpec{path, triple.isOSWindows() ? Style::windows : Style::posix} {}

namespace {
/// Safely get a character at the specified index.
///
/// \param[in] path
///     A full, partial, or relative path to a file.
///
/// \param[in] i
///     An index into path which may or may not be valid.
///
/// \return
///   The character at index \a i if the index is valid, or 0 if
///   the index is not valid.
inline char safeCharAtIndex(const llvm::StringRef &path, size_t i) {
  if (i < path.size())
    return path[i];
  return 0;
}

/// Check if a path needs to be normalized.
///
/// Check if a path needs to be normalized. We currently consider a
/// path to need normalization if any of the following are true
///  - path contains "/./"
///  - path contains "/../"
///  - path contains "//"
///  - path ends with "/"
/// Paths that start with "./" or with "../" are not considered to
/// need normalization since we aren't trying to resolve the path,
/// we are just trying to remove redundant things from the path.
///
/// \param[in] path
///     A full, partial, or relative path to a file.
///
/// \return
///   Returns \b true if the path needs to be normalized.
bool needsNormalization(const llvm::StringRef &path) {
  if (path.empty())
    return false;
  // We strip off leading "." values so these paths need to be normalized
  if (path[0] == '.')
    return true;
  for (auto i = path.find_first_of("\\/"); i != llvm::StringRef::npos;
       i = path.find_first_of("\\/", i + 1)) {
    const auto next = safeCharAtIndex(path, i+1);
    switch (next) {
      case 0:
        // path separator char at the end of the string which should be
        // stripped unless it is the one and only character
        return i > 0;
      case '/':
      case '\\':
        // two path separator chars in the middle of a path needs to be
        // normalized
        if (i > 0)
          return true;
        ++i;
        break;

      case '.': {
          const auto next_next = safeCharAtIndex(path, i+2);
          switch (next_next) {
            default: break;
            case 0: return true; // ends with "/."
            case '/':
            case '\\':
              return true; // contains "/./"
            case '.': {
              const auto next_next_next = safeCharAtIndex(path, i+3);
              switch (next_next_next) {
                default: break;
                case 0: return true; // ends with "/.."
                case '/':
                case '\\':
                  return true; // contains "/../"
              }
              break;
            }
          }
        }
        break;

      default:
        break;
    }
  }
  return false;
}


}

void FileSpec::SetFile(llvm::StringRef pathname) { SetFile(pathname, m_style); }

// Update the contents of this object with a new path. The path will be split
// up into a directory and filename and stored as uniqued string values for
// quick comparison and efficient memory usage.
void FileSpec::SetFile(llvm::StringRef pathname, Style style) {
  Clear();
  m_style = (style == Style::native) ? GetNativeStyle() : style;

  if (pathname.empty())
    return;

  llvm::SmallString<128> resolved(pathname);

  // Normalize the path by removing ".", ".." and other redundant components.
  if (needsNormalization(resolved))
    llvm::sys::path::remove_dots(resolved, true, m_style);

  // Normalize back slashes to forward slashes
  if (m_style == Style::windows)
    llvm::replace(resolved, '\\', '/');

  if (resolved.empty()) {
    // If we have no path after normalization set the path to the current
    // directory. This matches what python does and also a few other path
    // utilities.
    m_filename = ".";
    return;
  }

  // Split path into filename and directory. We rely on the underlying char
  // pointer to be nullptr when the components are empty.
  llvm::StringRef filename = llvm::sys::path::filename(resolved, m_style);
  if (!filename.empty())
    m_filename = filename;

  llvm::StringRef directory = llvm::sys::path::parent_path(resolved, m_style);
  if (!directory.empty())
    m_directory = directory;
}

void FileSpec::SetFile(llvm::StringRef path, const llvm::Triple &triple) {
  return SetFile(path, triple.isOSWindows() ? Style::windows : Style::posix);
}

// Convert to pointer operator. This allows code to check any FileSpec objects
// to see if they contain anything valid using code such as:
//
//  if (file_spec)
//  {}
FileSpec::operator bool() const {
  return !m_filename.empty() || !m_directory.empty();
}

// Logical NOT operator. This allows code to check any FileSpec objects to see
// if they are invalid using code such as:
//
//  if (!file_spec)
//  {}
bool FileSpec::operator!() const {
  return m_directory.empty() && m_filename.empty();
}

bool FileSpec::DirectoryEquals(const FileSpec &rhs) const {
  if (IsCaseSensitive() || rhs.IsCaseSensitive())
    return GetDirectory() == rhs.GetDirectory();
  return GetDirectory().equals_insensitive(rhs.GetDirectory());
}

bool FileSpec::FileEquals(const FileSpec &rhs) const {
  if (IsCaseSensitive() || rhs.IsCaseSensitive())
    return GetFilename() == rhs.GetFilename();
  return GetFilename().equals_insensitive(rhs.GetFilename());
}

// Equal to operator
bool FileSpec::operator==(const FileSpec &rhs) const {
  return FileEquals(rhs) && DirectoryEquals(rhs);
}

// Not equal to operator
bool FileSpec::operator!=(const FileSpec &rhs) const { return !(*this == rhs); }

// Less than operator
bool FileSpec::operator<(const FileSpec &rhs) const {
  return FileSpec::Compare(*this, rhs, true) < 0;
}

// Dump a FileSpec object to a stream
Stream &lldb_private::operator<<(Stream &s, const FileSpec &f) {
  f.Dump(s.AsRawOstream());
  return s;
}

// Clear this object by releasing both the directory and filename string values
// and making them both the empty string.
void FileSpec::Clear() {
  m_directory.clear();
  m_filename.clear();
  PathWasModified();
}

// Compare two FileSpec objects. If "full" is true, then both the directory and
// the filename must match. If "full" is false, then the directory names for
// "a" and "b" are only compared if they are both non-empty. This allows a
// FileSpec object to only contain a filename and it can match FileSpec objects
// that have matching filenames with different paths.
//
// Return -1 if the "a" is less than "b", 0 if "a" is equal to "b" and "1" if
// "a" is greater than "b".
int FileSpec::Compare(const FileSpec &a, const FileSpec &b, bool full) {
  int result = 0;

  // case sensitivity of compare
  const bool case_sensitive = a.IsCaseSensitive() || b.IsCaseSensitive();

  // If full is true, then we must compare both the directory and filename.

  // If full is false, then if either directory is empty, then we match on the
  // basename only, and if both directories have valid values, we still do a
  // full compare. This allows for matching when we just have a filename in one
  // of the FileSpec objects.

  if (full || (!a.m_directory.empty() && !b.m_directory.empty())) {
    if (case_sensitive)
      result = a.GetDirectory().compare(b.GetDirectory());
    else
      result = a.GetDirectory().compare_insensitive(b.GetDirectory());

    if (result)
      return result;
  }

  if (case_sensitive)
    result = a.GetFilename().compare(b.GetFilename());
  else
    result = a.GetFilename().compare_insensitive(b.GetFilename());

  return result;
}

bool FileSpec::Equal(const FileSpec &a, const FileSpec &b, bool full) {
  if (full || (!a.GetDirectory().empty() && !b.GetDirectory().empty()))
    return a == b;

  return a.FileEquals(b);
}

bool FileSpec::Match(const FileSpec &pattern, const FileSpec &file) {
  if (!pattern.GetDirectory().empty())
    return pattern == file;
  if (!pattern.GetFilename().empty())
    return pattern.FileEquals(file);
  return true;
}

std::optional<FileSpec::Style>
FileSpec::GuessPathStyle(llvm::StringRef absolute_path) {
  if (absolute_path.starts_with("/"))
    return Style::posix;
  if (absolute_path.starts_with(R"(\\)"))
    return Style::windows;
  if (absolute_path.size() >= 3 && llvm::isAlpha(absolute_path[0]) &&
      (absolute_path.substr(1, 2) == R"(:\)" ||
       absolute_path.substr(1, 2) == R"(:/)"))
    return Style::windows;
  return std::nullopt;
}

// Dump the object to the supplied stream. If the object contains a valid
// directory name, it will be displayed followed by a directory delimiter, and
// the filename.
void FileSpec::Dump(llvm::raw_ostream &s) const {
  std::string path{GetPath(true)};
  s << path;
  char path_separator = GetPreferredPathSeparator(m_style);
  if (m_filename.empty() && !path.empty() && path.back() != path_separator)
    s << path_separator;
}

llvm::json::Value FileSpec::ToJSON() const {
  std::string str;
  llvm::raw_string_ostream stream(str);
  this->Dump(stream);
  return llvm::json::Value(std::move(str));
}

FileSpec::Style FileSpec::GetPathStyle() const { return m_style; }

void FileSpec::SetDirectory(llvm::StringRef directory) {
  m_directory = directory;
  PathWasModified();
}

void FileSpec::SetFilename(llvm::StringRef filename) {
  m_filename = filename;
  PathWasModified();
}

void FileSpec::ClearFilename() {
  m_filename.clear();
  PathWasModified();
}

void FileSpec::ClearDirectory() {
  m_directory.clear();
  PathWasModified();
}

// Extract the directory and path into a fixed buffer. This is needed as the
// directory and path are stored in separate string values.
size_t FileSpec::GetPath(char *path, size_t path_max_len,
                         bool denormalize) const {
  if (!path)
    return 0;

  std::string result = GetPath(denormalize);
  ::snprintf(path, path_max_len, "%s", result.c_str());
  return std::min(path_max_len - 1, result.length());
}

std::string FileSpec::GetPath(bool denormalize) const {
  llvm::SmallString<64> result;
  GetPath(result, denormalize);
  return static_cast<std::string>(result);
}

void FileSpec::GetPath(llvm::SmallVectorImpl<char> &path,
                       bool denormalize) const {
  path.append(m_directory.begin(), m_directory.end());
  // Since the path was normalized and all paths use '/' when stored in these
  // objects, we don't need to look for the actual syntax specific path
  // separator, we just look for and insert '/'.
  if (!m_directory.empty() && !m_filename.empty() &&
      m_directory.back() != '/' && m_filename.back() != '/')
    path.insert(path.end(), '/');
  path.append(m_filename.begin(), m_filename.end());
  if (denormalize && !path.empty())
    Denormalize(path, m_style);
}

llvm::StringRef FileSpec::GetFileNameExtension() const {
  return llvm::sys::path::extension(m_filename, m_style);
}

llvm::StringRef FileSpec::GetFileNameStrippingExtension() const {
  return llvm::sys::path::stem(m_filename, m_style);
}

// Return the size in bytes that this object takes in memory. This returns the
// size in bytes of this object, not any shared string values it may refer to.
size_t FileSpec::MemorySize() const {
  return m_filename.size() + m_directory.size();
}

FileSpec
FileSpec::CopyByAppendingPathComponent(llvm::StringRef component) const {
  FileSpec ret = *this;
  ret.AppendPathComponent(component);
  return ret;
}

FileSpec FileSpec::CopyByRemovingLastPathComponent() const {
  llvm::SmallString<64> current_path;
  GetPath(current_path, false);
  if (llvm::sys::path::has_parent_path(current_path, m_style))
    return FileSpec(llvm::sys::path::parent_path(current_path, m_style),
                    m_style);
  return *this;
}

void FileSpec::PrependPathComponent(llvm::StringRef component) {
  llvm::SmallString<64> new_path(component);
  llvm::SmallString<64> current_path;
  GetPath(current_path, false);
  llvm::sys::path::append(new_path,
                          llvm::sys::path::begin(current_path, m_style),
                          llvm::sys::path::end(current_path), m_style);
  SetFile(new_path, m_style);
}

void FileSpec::PrependPathComponent(const FileSpec &new_path) {
  return PrependPathComponent(new_path.GetPath(false));
}

void FileSpec::AppendPathComponent(llvm::StringRef component) {
  llvm::SmallString<64> current_path;
  GetPath(current_path, false);
  llvm::sys::path::append(current_path, m_style, component);
  SetFile(current_path, m_style);
}

void FileSpec::AppendPathComponent(const FileSpec &new_path) {
  return AppendPathComponent(new_path.GetPath(false));
}

bool FileSpec::RemoveLastPathComponent() {
  llvm::SmallString<64> current_path;
  GetPath(current_path, false);
  if (llvm::sys::path::has_parent_path(current_path, m_style)) {
    SetFile(llvm::sys::path::parent_path(current_path, m_style));
    return true;
  }
  return false;
}

std::vector<llvm::StringRef> FileSpec::GetComponents() const {
  std::vector<llvm::StringRef> components;

  auto dir_begin = llvm::sys::path::begin(m_directory, m_style);
  auto dir_end = llvm::sys::path::end(m_directory);

  for (auto iter = dir_begin; iter != dir_end; ++iter) {
    if (*iter == "/" || *iter == ".")
      continue;

    components.push_back(*iter);
  }

  if (!m_filename.empty() && m_filename != "/" && m_filename != ".")
    components.push_back(m_filename);

  return components;
}

/// Returns true if the filespec represents an implementation source
/// file (files with a ".c", ".cpp", ".m", ".mm" (many more)
/// extension).
///
/// \return
///     \b true if the filespec represents an implementation source
///     file, \b false otherwise.
bool FileSpec::IsSourceImplementationFile() const {
  llvm::StringRef extension = GetFileNameExtension();
  if (extension.empty())
    return false;

  static RegularExpression g_source_file_regex(llvm::StringRef(
      "^.([cC]|[mM]|[mM][mM]|[cC][pP][pP]|[cC]\\+\\+|[cC][xX][xX]|[cC][cC]|["
      "cC][pP]|[sS]|[aA][sS][mM]|[fF]|[fF]77|[fF]90|[fF]95|[fF]03|[fF][oO]["
      "rR]|[fF][tT][nN]|[fF][pP][pP]|[aA][dD][aA]|[aA][dD][bB]|[aA][dD][sS])"
      "$"));
  return g_source_file_regex.Execute(extension);
}

bool FileSpec::IsRelative() const {
  return !IsAbsolute();
}

bool FileSpec::IsAbsolute() const {
  // Check if we have cached if this path is absolute to avoid recalculating.
  if (m_absolute != Absolute::Calculate)
    return m_absolute == Absolute::Yes;

  m_absolute = Absolute::No;

  llvm::SmallString<64> path;
  GetPath(path, false);

  if (!path.empty()) {
    // We consider paths starting with ~ to be absolute.
    if (path[0] == '~' || llvm::sys::path::is_absolute(path, m_style))
      m_absolute = Absolute::Yes;
  }

  return m_absolute == Absolute::Yes;
}

void FileSpec::MakeAbsolute(const FileSpec &dir) {
  if (IsRelative())
    PrependPathComponent(dir);
}

void llvm::format_provider<FileSpec>::format(const FileSpec &F,
                                             raw_ostream &Stream,
                                             StringRef Style) {
  assert((Style.empty() || Style.equals_insensitive("F") ||
          Style.equals_insensitive("D")) &&
         "Invalid FileSpec style!");

  StringRef dir = F.GetDirectory();
  StringRef file = F.GetFilename();

  if (dir.empty() && file.empty()) {
    Stream << "(empty)";
    return;
  }

  if (Style.equals_insensitive("F")) {
    Stream << (file.empty() ? "(empty)" : file);
    return;
  }

  // Style is either D or empty, either way we need to print the directory.
  if (!dir.empty()) {
    // Directory is stored in normalized form, which might be different than
    // preferred form.  In order to handle this, we need to cut off the
    // filename, then denormalize, then write the entire denorm'ed directory.
    llvm::SmallString<64> denormalized_dir = dir;
    Denormalize(denormalized_dir, F.GetPathStyle());
    Stream << denormalized_dir;
    Stream << GetPreferredPathSeparator(F.GetPathStyle());
  }

  if (Style.equals_insensitive("D")) {
    // We only want to print the directory, so now just exit.
    if (dir.empty())
      Stream << "(empty)";
    return;
  }

  if (!file.empty())
    Stream << file;
}
