// 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.
#ifndef BAZEL_SRC_MAIN_CPP_RC_FILE_H_
#define BAZEL_SRC_MAIN_CPP_RC_FILE_H_

#include <memory>
#include <string>
#include <vector>

#include "src/main/cpp/sem_ver.h"
#include "src/main/cpp/workspace_layout.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/function_ref.h"

namespace blaze {

// Single option in an rc file.
struct RcOption {
  std::string option;
  // Only keep the index of the source file to avoid copying the paths all over.
  // This index points into the RcFile's canonical_source_paths() vector.
  int source_index;
};

// Reads and parses a single rc file with all its imports.
class RcFile {
 public:
  // Constructs a parsed rc file object, or returns a nullptr and sets the
  // error and error text on failure.
  using ReadFileFn =
      absl::FunctionRef<bool(const std::string&, std::string*, std::string*)>;
  using CanonicalizePathFn = absl::FunctionRef<std::string(const std::string&)>;
  enum class ParseError {
    NONE,
    UNREADABLE_FILE,
    INVALID_FORMAT,
    IMPORT_LOOP,
    IMPORT_DEPTH_EXCEEDED
  };
  static constexpr int MaxImportDepth = 512;
  static std::unique_ptr<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 = MaxImportDepth,
      ReadFileFn read_file = &ReadFileDefault,
      CanonicalizePathFn canonicalize_path = &CanonicalizePathDefault);

  static std::unique_ptr<RcFile> Parse(
      const std::string& filename, const WorkspaceLayout* workspace_layout,
      const std::string& workspace, ParseError* error, std::string* error_text,
      ReadFileFn read_file = &ReadFileDefault,
      CanonicalizePathFn canonicalize_path = &CanonicalizePathDefault);

  // Command -> all options for that command (in order of appearance).
  using OptionMap = absl::flat_hash_map<std::string, std::vector<RcOption>>;

  static bool ReadFileDefault(const std::string& filename,
                              std::string* contents, std::string* error_msg);
  static std::string CanonicalizePathDefault(const std::string& filename);

  static std::unique_ptr<RcFile> Create(
      std::vector<std::string> canonical_rcfile_paths, OptionMap options);

  // Movable and copyable.
  RcFile(const RcFile&) = default;
  RcFile(RcFile&&) = default;
  RcFile& operator=(const RcFile&) = default;
  RcFile& operator=(RcFile&&) = default;

  // Returns all relevant rc sources for this file (including itself).
  const std::vector<std::string>& canonical_source_paths() const {
    return canonical_rcfile_paths_;
  }

  const OptionMap& options() const { return options_; }

 private:
  RcFile() = default;

  // Recursive call to parse a file and its imports.
  ParseError 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);

  ParseError 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);

  // Full closure of rcfile paths imported from this file (including itself).
  // These are all canonical paths, created with blaze_util::MakeCanonical.
  // This also means all of these paths should exist.
  std::vector<std::string> canonical_rcfile_paths_;
  // All options parsed from the file.
  OptionMap options_;
};

// Checks if the build label passes the given comparison operation and
// condition. An empty return (nullopt) indicates a failure and error_text will
// be filled.
//
// Eg. The following values would evaluate to true since 8.4.5 >= 5.4.0
//  - build_label=8.4.5
//  - op='>='
//  - compare_version=5.4.0
std::optional<bool> BazelVersionMatchesCondition(
    const SemVer& build_label, absl::string_view op,
    const std::string& compare_version, std::string* error_text);

}  // namespace blaze

#endif  // BAZEL_SRC_MAIN_CPP_RC_FILE_H_
