// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/main/cpp/rc_file.h"

#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "src/main/cpp/blaze_util_platform.h"
#include "src/main/cpp/sem_ver.h"
#include "src/main/cpp/util/file_platform.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/strings.h"
#include "src/main/cpp/workspace_layout.h"
#include "absl/algorithm/container.h"
#include "absl/functional/function_ref.h"
#include "absl/memory/memory.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "re2/re2.h"

namespace blaze {

static constexpr absl::string_view kCommandImport = "import";
static constexpr absl::string_view kCommandTryImport = "try-import";
static constexpr absl::string_view kCommandTryImportIfBazelVersion =
    "try-import-if-bazel-version";

// The valid operators to compare against bazel version for
// kCommandTryImportIfBazelVersion. These should match the below regex.
static constexpr absl::string_view kBazelVersionLt = "<";
static constexpr absl::string_view kBazelVersionLte = "<=";
static constexpr absl::string_view kBazelVersionGt = ">";
static constexpr absl::string_view kBazelVersionGte = ">=";
static constexpr absl::string_view kBazelVersionEq = "==";
static constexpr absl::string_view kBazelVersionNeq = "!=";
static constexpr absl::string_view kBazelVersionTilde = "~";

// Regex to match the comparison operator in kCommandTryImportIfBazelVersion
// statements. Eg. '>=9.0.0'
const LazyRE2 kBazelVersionCmpOp = {R"((<=?|>=?|==|!=|~)(\S+))"};

/*static*/ std::unique_ptr<RcFile> RcFile::Parse(
    const std::string& filename, const WorkspaceLayout* workspace_layout,
    const std::string& workspace, const std::string& build_label,
    const std::optional<SemVer>& sem_ver, ParseError* error,
    std::string* error_text, int max_import_depth, ReadFileFn read_file,
    CanonicalizePathFn canonicalize_path) {
  auto rcfile = absl::WrapUnique(new RcFile());
  std::vector<std::string> initial_import_stack = {filename};
  *error = rcfile->ParseFile(filename, workspace, *workspace_layout,
                             build_label, sem_ver, read_file, canonicalize_path,
                             initial_import_stack, error_text, max_import_depth,
                             /*current_depth=*/0);
  return (*error == ParseError::NONE) ? std::move(rcfile) : nullptr;
}

/*static*/ std::unique_ptr<RcFile> RcFile::Parse(
    const std::string& filename, const WorkspaceLayout* workspace_layout,
    const std::string& workspace, ParseError* error, std::string* error_text,
    ReadFileFn read_file, CanonicalizePathFn canonicalize_path) {
  return Parse(filename, workspace_layout, workspace, /*build_label=*/"",
               /*sem_ver=*/std::nullopt, error, error_text,
               /*max_import_depth=*/MaxImportDepth, read_file,
               canonicalize_path);
}

std::unique_ptr<RcFile> RcFile::Create(
    std::vector<std::string> canonical_rcfile_paths, OptionMap options) {
  auto rc_file = absl::WrapUnique(new RcFile());
  rc_file->canonical_rcfile_paths_ = std::move(canonical_rcfile_paths);
  rc_file->options_ = std::move(options);
  return rc_file;
}

RcFile::ParseError RcFile::ParseFile(
    const std::string& filename, const std::string& workspace,
    const WorkspaceLayout& workspace_layout, const std::string& build_label,
    const std::optional<SemVer>& sem_ver, ReadFileFn read_file,
    CanonicalizePathFn canonicalize_path,
    std::vector<std::string>& import_stack, std::string* error_text,
    int max_import_depth, int current_depth) {
  BAZEL_LOG(INFO) << "Parsing the RcFile " << filename;
  if (current_depth > max_import_depth) {
    *error_text = absl::StrFormat(
        "Maximum import depth exceeded parsing config file '%s'", filename);
    return ParseError::IMPORT_DEPTH_EXCEEDED;
  }
  std::string contents;
  if (std::string error_msg; !read_file(filename, &contents, &error_msg)) {
    *error_text = absl::StrFormat(
        "Unexpected error reading config file '%s': %s", filename, error_msg);
    return ParseError::UNREADABLE_FILE;
  }
  const std::string canonical_filename = canonicalize_path(filename);

  int rcfile_index = canonical_rcfile_paths_.size();
  canonical_rcfile_paths_.push_back(canonical_filename);

  // A '\' at the end of a line continues the line.
  blaze_util::Replace("\\\r\n", "", &contents);
  blaze_util::Replace("\\\n", "", &contents);

  std::vector<std::string> lines = absl::StrSplit(contents, '\n');
  for (std::string& line : lines) {
    blaze_util::StripWhitespace(&line);

    // Check for an empty line.
    if (line.empty()) continue;

    std::vector<std::string> words;

    // This will treat "#" as a comment, and properly
    // quote single and double quotes, and treat '\'
    // as an escape character.
    // TODO(bazel-team): This function silently ignores
    // dangling backslash escapes and missing end-quotes.
    blaze_util::Tokenize(line, '#', &words);

    // Could happen if line starts with "#"
    if (words.empty()) continue;

    const absl::string_view command = words[0];
    if (command != kCommandImport && command != kCommandTryImport &&
        command != kCommandTryImportIfBazelVersion) {
      if (words.size() == 1 && absl::StrContains(command, ':')) {
        // Preserve empty config declarations so the server can tell they exist.
        options_[command].push_back({"", rcfile_index});
      }
      for (absl::string_view word : absl::MakeConstSpan(words).subspan(1)) {
        options_[command].push_back({std::string(word), rcfile_index});
      }
      continue;
    }

    if ((command == kCommandTryImportIfBazelVersion && words.size() != 3) ||
        (command != kCommandTryImportIfBazelVersion && words.size() != 2)) {
      *error_text = absl::StrFormat(
          "Invalid import declaration in config file '%s': '%s'",
          canonical_filename, line);
      return ParseError::INVALID_FORMAT;
    }

    std::string import_filename;
    if (command == kCommandImport || command == kCommandTryImport) {
      import_filename = words[1];
    } else {  // command == kCommandTryImportIfBazelVersion
      if (!sem_ver.has_value()) {
        BAZEL_LOG(INFO) << absl::StrFormat(
            "Skipping '%s' import because bazel build label '%s' is not a "
            "valid semantic version.",
            line, build_label);
        continue;
      }
      const auto& conditional = words[1];
      import_filename = words[2];

      absl::string_view op;
      std::string version;
      if (RE2::FullMatch(conditional, *kBazelVersionCmpOp, &op, &version)) {
        std::optional<bool> match = BazelVersionMatchesCondition(
            sem_ver.value(), op, version, error_text);
        if (!match.has_value()) {
          // Annotate the existing error_text filled by the function.
          *error_text = absl::StrFormat(
              "Invalid import declaration in config file '%s': '%s'. %s",
              canonical_filename, line, *error_text);
          return ParseError::INVALID_FORMAT;
        }

        if (!match.value()) {
          BAZEL_LOG(INFO) << absl::StrFormat(
              "Skipped optional import '%s' because the condition (%s) did not "
              "match the current running Bazel version (%s)",
              line, conditional, build_label);
          continue;
        }
      } else {
        *error_text = absl::StrFormat(
            "Invalid version condition in config file '%s': '%s'. Condition "
            "'%s'. A valid condition is one of the following 7 comparison "
            "operators ('<', '<=', '>', '>=', '==', '!=', '~') followed by a "
            "semantic version.",
            canonical_filename, line, conditional);

        return ParseError::INVALID_FORMAT;
      }
    }

    if (absl::StartsWith(import_filename, WorkspaceLayout::kWorkspacePrefix)) {
      const auto resolved_filename =
          workspace_layout.ResolveWorkspaceRelativeRcFilePath(workspace,
                                                              import_filename);
      if (!resolved_filename.has_value()) {
        if (command == kCommandImport) {
          *error_text = absl::StrFormat(
              "Nonexistent path in import declaration in config file '%s': '%s'"
              " (are you in your source checkout/WORKSPACE?)",
              canonical_filename, line);
          return ParseError::INVALID_FORMAT;
        }
        // For try-import, we ignore it if we couldn't find a file.
        BAZEL_LOG(INFO) << "Skipped optional import of " << import_filename
                        << ", the specified rc file either does not exist or "
                        << "is not readable.";
        continue;
      }

      import_filename = resolved_filename.value();
    }

    if (absl::c_linear_search(import_stack, import_filename)) {
      std::string loop;
      for (const std::string& imported_rc : import_stack) {
        absl::StrAppend(&loop, "  ", imported_rc, "\n");
      }
      absl::StrAppend(&loop, "  ", import_filename, "\n");  // Include the loop.
      *error_text = absl::StrCat("Import loop detected:\n", loop);
      return ParseError::IMPORT_LOOP;
    }

    import_stack.push_back(import_filename);
    if (ParseError parse_error =
            ParseFile(import_filename, workspace, workspace_layout, build_label,
                      sem_ver, read_file, canonicalize_path, import_stack,
                      error_text, max_import_depth, current_depth + 1);
        parse_error != ParseError::NONE) {
      if (parse_error == ParseError::UNREADABLE_FILE &&
          (command == kCommandTryImport ||
           command == kCommandTryImportIfBazelVersion)) {
        // For try-import.*, we ignore it if we couldn't find a file.
        BAZEL_LOG(INFO) << "Skipped optional import of " << import_filename
                        << ", the specified rc file either does not exist or "
                           "is not readable.";
        *error_text = "";
      } else {
        // Files that are there but are malformed or introduce a loop are
        // still a problem, though, so perpetuate those errors as we would
        // for a normal import statement.
        return parse_error;
      }
    }
    import_stack.pop_back();
  }

  return ParseError::NONE;
}

RcFile::ParseError RcFile::ParseFile(
    const std::string& filename, const std::string& workspace,
    const WorkspaceLayout& workspace_layout, ReadFileFn read_file,
    CanonicalizePathFn canonicalize_path,
    std::vector<std::string>& import_stack, std::string* error_text) {
  return ParseFile(filename, workspace, workspace_layout, /*build_label=*/"",
                   /*sem_ver=*/std::nullopt, read_file, canonicalize_path,
                   import_stack, error_text,
                   /*max_import_depth=*/RcFile::MaxImportDepth,
                   /*current_depth=*/0);
}

bool RcFile::ReadFileDefault(const std::string& filename, std::string* contents,
                             std::string* error_msg) {
  return blaze_util::ReadFile(filename, contents, error_msg);
}

std::string RcFile::CanonicalizePathDefault(const std::string& filename) {
  return blaze_util::MakeCanonical(filename.c_str());
}

std::optional<bool>
BazelVersionMatchesCondition(const SemVer& build_label, absl::string_view op,
                             const std::string& compare_version,
                             std::string* error_text) {
  if (op == kBazelVersionTilde) {
    // For the tilde operator, the version string after the operator can be a
    // partial semantic version (i.e. '8' instead of '8.0.0' or '8.2' instead of
    // '8.2.0'). Append additional parts to make it a valid semantic version.
    const auto num_dots =
        std::count(compare_version.begin(), compare_version.end(), '.');

    std::optional<SemVer> semver_compare_version;
    if (num_dots == 0) {  // 8 -> 8.0.0
      semver_compare_version =
          SemVer::Parse(absl::StrCat(compare_version, ".0.0"));
    } else if (num_dots == 1) {  // 8.2 -> 8.2.0
      semver_compare_version =
          SemVer::Parse(absl::StrCat(compare_version, ".0"));
    } else {  // Assume a valid semantic version.
      semver_compare_version = SemVer::Parse(compare_version);
    }
    if (!semver_compare_version.has_value()) {
      *error_text = absl::StrFormat("Could not parse the tilde range version "
                                    "'%s' as a valid semantic version.",
                                    compare_version);
      return std::nullopt;
    }
    if (num_dots == 0) {  // eg. ~8 => version >= 8.0.0 && version < 9.0.0
      return build_label >= semver_compare_version.value() &&
             build_label < semver_compare_version->NextMajorVersion();
    }
    // eg. ~8.1 => version >= 8.1.0 && version < 8.2.0
    // eg. ~8.1.4 => version >= 8.1.4 && version < 8.2.0
    return build_label >= semver_compare_version.value() &&
           build_label < semver_compare_version->NextMinorVersion();
  }

  std::optional<SemVer> semver_compare_version =
      SemVer::Parse(compare_version);
  if (!semver_compare_version.has_value()) {
    *error_text = absl::StrFormat(
        "Could not parse version '%s' as a valid semantic version.",
        compare_version);
    return std::nullopt;
  }

  if (op == kBazelVersionLt) {
    return build_label < semver_compare_version;
  } else if (op == kBazelVersionLte) {
    return build_label <= semver_compare_version;
  } else if (op == kBazelVersionGt) {
    return build_label > semver_compare_version;
  } else if (op == kBazelVersionGte) {
    return build_label >= semver_compare_version;
  } else if (op == kBazelVersionEq) {
    return build_label == semver_compare_version;
  } else if (op == kBazelVersionNeq) {
    return build_label != semver_compare_version;
  }

  // We should never get here since only a valid op should be passed in.
  *error_text = absl::StrFormat("Invalid comparison operator '%s'.", op);
  return std::nullopt;
}

}  // namespace blaze
