/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Glob.hxx)

#include KWSYS_HEADER(Configure.hxx)

#include KWSYS_HEADER(RegularExpression.hxx)
#include KWSYS_HEADER(SystemTools.hxx)
#include KWSYS_HEADER(Directory.hxx)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
#include "Configure.hxx.in"
#include "Directory.hxx.in"
#include "Glob.hxx.in"
#include "RegularExpression.hxx.in"
#include "SystemTools.hxx.in"
#endif

#include <algorithm>
#include <string>
#include <vector>

#include <ctype.h>
#include <stdio.h>
#include <string.h>
namespace KWSYS_NAMESPACE {
#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
// On Windows and apple, no difference between lower and upper case
#define KWSYS_GLOB_CASE_INDEPENDENT
#endif

#if defined(_WIN32) || defined(__CYGWIN__)
// Handle network paths
#define KWSYS_GLOB_SUPPORT_NETWORK_PATHS
#endif

class GlobInternals
{
public:
  std::vector<std::string> Files;
  std::vector<kwsys::RegularExpression> Expressions;
};

Glob::Glob()
{
  this->Internals = new GlobInternals;
  this->Recurse = false;
  this->Relative = "";

  this->RecurseThroughSymlinks = true;
  // RecurseThroughSymlinks is true by default for backwards compatibility,
  // not because it's a good idea...
  this->FollowedSymlinkCount = 0;

  // Keep separate variables for directory listing for back compatibility
  this->ListDirs = true;
  this->RecurseListDirs = false;
}

Glob::~Glob()
{
  delete this->Internals;
}

std::vector<std::string>& Glob::GetFiles()
{
  return this->Internals->Files;
}

std::string Glob::PatternToRegex(const std::string& pattern,
                                 bool require_whole_string, bool preserve_case)
{
  // Incrementally build the regular expression from the pattern.
  std::string regex = require_whole_string ? "^" : "";
  std::string::const_iterator pattern_first = pattern.begin();
  std::string::const_iterator pattern_last = pattern.end();
  for (std::string::const_iterator i = pattern_first; i != pattern_last; ++i) {
    int c = *i;
    if (c == '*') {
      // A '*' (not between brackets) matches any string.
      // We modify this to not match slashes since the orignal glob
      // pattern documentation was meant for matching file name
      // components separated by slashes.
      regex += "[^/]*";
    } else if (c == '?') {
      // A '?' (not between brackets) matches any single character.
      // We modify this to not match slashes since the orignal glob
      // pattern documentation was meant for matching file name
      // components separated by slashes.
      regex += "[^/]";
    } else if (c == '[') {
      // Parse out the bracket expression.  It begins just after the
      // opening character.
      std::string::const_iterator bracket_first = i + 1;
      std::string::const_iterator bracket_last = bracket_first;

      // The first character may be complementation '!' or '^'.
      if (bracket_last != pattern_last &&
          (*bracket_last == '!' || *bracket_last == '^')) {
        ++bracket_last;
      }

      // If the next character is a ']' it is included in the brackets
      // because the bracket string may not be empty.
      if (bracket_last != pattern_last && *bracket_last == ']') {
        ++bracket_last;
      }

      // Search for the closing ']'.
      while (bracket_last != pattern_last && *bracket_last != ']') {
        ++bracket_last;
      }

      // Check whether we have a complete bracket string.
      if (bracket_last == pattern_last) {
        // The bracket string did not end, so it was opened simply by
        // a '[' that is supposed to be matched literally.
        regex += "\\[";
      } else {
        // Convert the bracket string to its regex equivalent.
        std::string::const_iterator k = bracket_first;

        // Open the regex block.
        regex += "[";

        // A regex range complement uses '^' instead of '!'.
        if (k != bracket_last && *k == '!') {
          regex += "^";
          ++k;
        }

        // Convert the remaining characters.
        for (; k != bracket_last; ++k) {
          // Backslashes must be escaped.
          if (*k == '\\') {
            regex += "\\";
          }

          // Store this character.
          regex += *k;
        }

        // Close the regex block.
        regex += "]";

        // Jump to the end of the bracket string.
        i = bracket_last;
      }
    } else {
      // A single character matches itself.
      int ch = c;
      if (!(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
            ('0' <= ch && ch <= '9'))) {
        // Escape the non-alphanumeric character.
        regex += "\\";
      }
#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
      else {
        // On case-insensitive systems file names are converted to lower
        // case before matching.
        if (!preserve_case) {
          ch = tolower(ch);
        }
      }
#endif
      (void)preserve_case;
      // Store the character.
      regex.append(1, static_cast<char>(ch));
    }
  }

  if (require_whole_string) {
    regex += "$";
  }
  return regex;
}

bool Glob::RecurseDirectory(std::string::size_type start,
                            const std::string& dir, GlobMessages* messages)
{
  kwsys::Directory d;
  if (!d.Load(dir)) {
    return true;
  }
  unsigned long cc;
  std::string realname;
  std::string fname;
  for (cc = 0; cc < d.GetNumberOfFiles(); cc++) {
    fname = d.GetFile(cc);
    if (fname == "." || fname == "..") {
      continue;
    }

    if (start == 0) {
      realname = dir + fname;
    } else {
      realname = dir + "/" + fname;
    }

#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
    // On Windows and apple, no difference between lower and upper case
    fname = kwsys::SystemTools::LowerCase(fname);
#endif

    bool isDir = kwsys::SystemTools::FileIsDirectory(realname);
    bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname);

    if (isDir && (!isSymLink || this->RecurseThroughSymlinks)) {
      if (isSymLink) {
        ++this->FollowedSymlinkCount;
        std::string realPathErrorMessage;
        std::string canonicalPath(
          SystemTools::GetRealPath(dir, &realPathErrorMessage));

        if (!realPathErrorMessage.empty()) {
          if (messages) {
            messages->push_back(Message(
              Glob::error, "Canonical path generation from path '" + dir +
                "' failed! Reason: '" + realPathErrorMessage + "'"));
          }
          return false;
        }

        if (std::find(this->VisitedSymlinks.begin(),
                      this->VisitedSymlinks.end(),
                      canonicalPath) == this->VisitedSymlinks.end()) {
          if (this->RecurseListDirs) {
            // symlinks are treated as directories
            this->AddFile(this->Internals->Files, realname);
          }

          this->VisitedSymlinks.push_back(canonicalPath);
          if (!this->RecurseDirectory(start + 1, realname, messages)) {
            this->VisitedSymlinks.pop_back();

            return false;
          }
          this->VisitedSymlinks.pop_back();
        }
        // else we have already visited this symlink - prevent cyclic recursion
        else if (messages) {
          std::string message;
          for (std::vector<std::string>::const_iterator pathIt =
                 std::find(this->VisitedSymlinks.begin(),
                           this->VisitedSymlinks.end(), canonicalPath);
               pathIt != this->VisitedSymlinks.end(); ++pathIt) {
            message += *pathIt + "\n";
          }
          message += canonicalPath + "/" + fname;
          messages->push_back(Message(Glob::cyclicRecursion, message));
        }
      } else {
        if (this->RecurseListDirs) {
          this->AddFile(this->Internals->Files, realname);
        }
        if (!this->RecurseDirectory(start + 1, realname, messages)) {
          return false;
        }
      }
    } else {
      if (!this->Internals->Expressions.empty() &&
          this->Internals->Expressions.rbegin()->find(fname)) {
        this->AddFile(this->Internals->Files, realname);
      }
    }
  }

  return true;
}

void Glob::ProcessDirectory(std::string::size_type start,
                            const std::string& dir, GlobMessages* messages)
{
  // std::cout << "ProcessDirectory: " << dir << std::endl;
  bool last = (start == this->Internals->Expressions.size() - 1);
  if (last && this->Recurse) {
    this->RecurseDirectory(start, dir, messages);
    return;
  }

  if (start >= this->Internals->Expressions.size()) {
    return;
  }

  kwsys::Directory d;
  if (!d.Load(dir)) {
    return;
  }
  unsigned long cc;
  std::string realname;
  std::string fname;
  for (cc = 0; cc < d.GetNumberOfFiles(); cc++) {
    fname = d.GetFile(cc);
    if (fname == "." || fname == "..") {
      continue;
    }

    if (start == 0) {
      realname = dir + fname;
    } else {
      realname = dir + "/" + fname;
    }

#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
    // On case-insensitive file systems convert to lower case for matching.
    fname = kwsys::SystemTools::LowerCase(fname);
#endif

    // std::cout << "Look at file: " << fname << std::endl;
    // std::cout << "Match: "
    // << this->Internals->TextExpressions[start].c_str() << std::endl;
    // std::cout << "Real name: " << realname << std::endl;

    if ((!last && !kwsys::SystemTools::FileIsDirectory(realname)) ||
        (!this->ListDirs && last &&
         kwsys::SystemTools::FileIsDirectory(realname))) {
      continue;
    }

    if (this->Internals->Expressions[start].find(fname)) {
      if (last) {
        this->AddFile(this->Internals->Files, realname);
      } else {
        this->ProcessDirectory(start + 1, realname, messages);
      }
    }
  }
}

bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
{
  std::string cexpr;
  std::string::size_type cc;
  std::string expr = inexpr;

  this->Internals->Expressions.clear();
  this->Internals->Files.clear();

  if (!kwsys::SystemTools::FileIsFullPath(expr)) {
    expr = kwsys::SystemTools::GetCurrentWorkingDirectory();
    expr += "/" + inexpr;
  }
  std::string fexpr = expr;

  std::string::size_type skip = 0;
  std::string::size_type last_slash = 0;
  for (cc = 0; cc < expr.size(); cc++) {
    if (cc > 0 && expr[cc] == '/' && expr[cc - 1] != '\\') {
      last_slash = cc;
    }
    if (cc > 0 && (expr[cc] == '[' || expr[cc] == '?' || expr[cc] == '*') &&
        expr[cc - 1] != '\\') {
      break;
    }
  }
  if (last_slash > 0) {
    // std::cout << "I can skip: " << fexpr.substr(0, last_slash)
    // << std::endl;
    skip = last_slash;
  }
  if (skip == 0) {
#if defined(KWSYS_GLOB_SUPPORT_NETWORK_PATHS)
    // Handle network paths
    if (expr[0] == '/' && expr[1] == '/') {
      int cnt = 0;
      for (cc = 2; cc < expr.size(); cc++) {
        if (expr[cc] == '/') {
          cnt++;
          if (cnt == 2) {
            break;
          }
        }
      }
      skip = int(cc + 1);
    } else
#endif
      // Handle drive letters on Windows
      if (expr[1] == ':' && expr[0] != '/') {
      skip = 2;
    }
  }

  if (skip > 0) {
    expr = expr.substr(skip);
  }

  cexpr = "";
  for (cc = 0; cc < expr.size(); cc++) {
    int ch = expr[cc];
    if (ch == '/') {
      if (!cexpr.empty()) {
        this->AddExpression(cexpr);
      }
      cexpr = "";
    } else {
      cexpr.append(1, static_cast<char>(ch));
    }
  }
  if (!cexpr.empty()) {
    this->AddExpression(cexpr);
  }

  // Handle network paths
  if (skip > 0) {
    this->ProcessDirectory(0, fexpr.substr(0, skip) + "/", messages);
  } else {
    this->ProcessDirectory(0, "/", messages);
  }
  return true;
}

void Glob::AddExpression(const std::string& expr)
{
  this->Internals->Expressions.push_back(
    kwsys::RegularExpression(this->PatternToRegex(expr)));
}

void Glob::SetRelative(const char* dir)
{
  if (!dir) {
    this->Relative = "";
    return;
  }
  this->Relative = dir;
}

const char* Glob::GetRelative()
{
  if (this->Relative.empty()) {
    return 0;
  }
  return this->Relative.c_str();
}

void Glob::AddFile(std::vector<std::string>& files, const std::string& file)
{
  if (!this->Relative.empty()) {
    files.push_back(kwsys::SystemTools::RelativePath(this->Relative, file));
  } else {
    files.push_back(file);
  }
}

} // namespace KWSYS_NAMESPACE
