// Copyright 2017-2020 The Verible Authors.
//
// 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 VERIBLE_COMMON_ANALYSIS_LINT_WAIVER_H_
#define VERIBLE_COMMON_ANALYSIS_LINT_WAIVER_H_

#include <cstddef>
#include <map>
#include <regex>  // NOLINT
#include <set>
#include <vector>

#include "absl/strings/string_view.h"
#include "common/strings/position.h"
#include "common/text/text_structure.h"
#include "common/text/token_stream_view.h"
#include "common/util/container_util.h"
#include "common/util/interval_set.h"

namespace verible {

// LintWaiver maintains a set of line ranges per lint rule that should be
// exempt from each rule.
class LintWaiver {
  using RegexVector = std::vector<const std::regex*>;

 public:
  LintWaiver() {}

  // Construction either done in Builder function or LintWaiverBuilder class
  // defined below.
  // void Initialize(const LintWaiverBuilder&);  // or configuration

  // Scan lines for comments with linter directives.
  // Lines with only space/comment tokens will apply to the next line that
  // doesn't contain only spaces and newlines.  Blank line will cancel the
  // waiver.
  // Waiver comments on lines with other tokens will only waive that line.

  // Adds a single line to the set of waived lines for a single rule.
  void WaiveOneLine(absl::string_view rule_name, int line_number);

  // Adds a range [line_begin, line_end) over which a waiver applies.
  void WaiveLineRange(absl::string_view rule_name, int line_begin,
                      int line_end);

  // Adds a regular expression which will be used to apply a waiver.
  void WaiveWithRegex(absl::string_view rule_name, const std::string& regex);

  // Converts the prepared regular expressions to line numbers and applies the
  // waivers.
  void RegexToLines(absl::string_view content, const LineColumnMap& line_map);

  // Returns true if `line_number` should be waived for a particular rule.
  bool RuleIsWaivedOnLine(absl::string_view rule_name, int line_number) const;

  // Returns true if there are no lines waived for any rules.
  bool Empty() const;

  // TODO(hzeller): The following methods break abstraction and are only
  // for performance. Reconsider if this is worth it.
  const LineNumberSet* LookupLineNumberSet(absl::string_view rule_name) const {
    return verible::container::FindOrNull(waiver_map_, rule_name);
  }

  // Test if a particular line is included in the set.
  static bool LineNumberSetContains(const LineNumberSet& line_set, int line) {
    return line_set.Contains(line);
  }

 private:
  // Keys in the maps below are the names of the waived rules. They can be
  // string_view because the static strings for each lint rule class exist,
  // and will outlive all LintWaiver objects. This applies to both waiver_map_
  // and waiver_re_map_.
  std::map<absl::string_view, LineNumberSet> waiver_map_;
  std::map<absl::string_view, RegexVector> waiver_re_map_;

  std::map<std::string, std::regex> regex_cache_;
};

// LintWaiverBuilder is a language-agnostic helper class for constructing
// LintWaiver maps.  Objects of this builder type become language-specific
// through function hooks passed to the constructor.
// Alternately, a derived class can bind the constructor arguments for a
// language-specific implementation.
//
// A waiver comment on its own line applies the waiver to the next
// non-comment-line.
//
//   1: // tool_name rule_name waive
//   2: other text, this line is waived
//
// A waiver comment on a line with other non-comment text waives its own line:
//
//   1: blah blah  // tool_name rule_name waive // waives this line only
//
// TODO(fangism): Support lint waiver directives in multi-line block comments.
class LintWaiverBuilder {
 public:
  // 'is_comment' returns true if the token passed is considered a comment.
  // 'is_space' returns true if token represents whitespace.
  // 'trigger' is the string that triggers waiver processing, often a tool name.
  //   The first argument after the trigger is the name of the rule to waive.
  // 'waive_command' is the second argument after the trigger, and is the
  //   command for 'waive-one-line'.
  LintWaiverBuilder(TokenFilterPredicate&& is_comment,
                    TokenFilterPredicate&& is_space, absl::string_view trigger,
                    absl::string_view waive_line_command,
                    absl::string_view waive_start_command,
                    absl::string_view waive_stop_command)
      : waiver_trigger_keyword_(trigger),
        waive_one_line_keyword_(waive_line_command),
        waive_range_start_keyword_(waive_start_command),
        waive_range_stop_keyword_(waive_stop_command),
        is_token_comment_(std::move(is_comment)),
        is_token_whitespace_(std::move(is_space)) {}

  // Takes a single line's worth of tokens and determines updates to the set of
  // waived lines.  Pass a slice of tokens using make_range.
  void ProcessLine(const TokenRange& tokens, int line_number);

  // Takes a lexically analyzed text structure and determines the entire set of
  // waived lines.  This can be more easily unit-tested using
  // TextStructureTokenized from text_structure_test_utils.h.
  void ProcessTokenRangesByLine(const TextStructureView&);

  // Takes a set of active linter rules and the affected filename to be linted,
  // and applies waivers from waiver_filename and its content.
  absl::Status ApplyExternalWaivers(
      const std::set<absl::string_view>& active_rules,
      absl::string_view lintee_filename, absl::string_view waiver_filename,
      absl::string_view waivers_config_content);

  const LintWaiver& GetLintWaiver() const { return lint_waiver_; }

 protected:
  // Parses a comment and extracts a waived rule name.
  // If text does not match the waived form, then return an empty string.
  // `comment_tokens` is just re-used memory to avoid re-allocation.
  absl::string_view ExtractWaivedRuleFromComment(
      absl::string_view comment_text,
      std::vector<absl::string_view>* comment_tokens) const;

  // Special string that leads a comment that is a waiver directive
  // Typically, name of linter tool is used here.
  absl::string_view waiver_trigger_keyword_;

  // Command to waive one line, either the current line if there are tokens
  // on the current line or the next non-comment-non-blank-line.
  absl::string_view waive_one_line_keyword_;  // e.g. "waive"

  // Command pair to start and stop waiving ranges of lines.
  // e.g. "waive-start", "waive-stop"
  absl::string_view waive_range_start_keyword_;
  absl::string_view waive_range_stop_keyword_;

  // Returns true if token is a comment.
  TokenFilterPredicate is_token_comment_;

  // Returns true if token is a whitespace (still considered blank).
  TokenFilterPredicate is_token_whitespace_;

  // This holds the set of to-be-applied lint waivers.
  // Element string_views point to string memory that outlives this builder.
  std::set<absl::string_view> unapplied_oneline_waivers_;

  // This holds the set of open ranges of lines, keyed by rule name.
  // Value is the lower-bound of each encountered waiver range.
  // string_view keys point to string memory that outlives this builder.
  std::map<absl::string_view, int> waiver_open_ranges_;

  // Set of waived lines per rule.
  LintWaiver lint_waiver_;
};

}  // namespace verible

#endif  // VERIBLE_COMMON_ANALYSIS_LINT_WAIVER_H_
