// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_FIDL_FIDLC_INCLUDE_FIDL_LINTER_H_
#define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_LINTER_H_

#include <array>
#include <deque>
#include <regex>
#include <set>

#include <fidl/check_def.h>
#include <fidl/findings.h>
#include <fidl/linting_tree_callbacks.h>
#include <fidl/tree_visitor.h>
#include <fidl/utils.h>

namespace fidl {
namespace linter {

// The primary business logic for lint-checks on a FIDL file is implemented in
// the |Linter| class. This class is not thread safe.
class Linter {
 public:
  // On initialization, the |Linter| constructs the |CheckDef|
  // objects with associated check logic (lambdas registered via
  // |CheckCallbacks|).
  Linter();

  // If a user specifies the command line flag --include-check=<check-id>
  // (one or more times) without any --exclude_check flags, the default
  // state is to exclude all checks EXCEPT those specifically indicated.
  void set_exclude_by_default(bool exclude_by_default) { exclude_by_default_ = exclude_by_default; }

  // Copies the given list of check-ids to be included, if otherwise excluded or disabled.
  // By default, all checks are included unless explicitly disabled (see linter/main.cc), excluded
  // by command line option, or if |excluded_by_default| is set to true.
  void set_included_checks(const std::set<std::string>& included_check_ids) {
    included_check_ids_ = included_check_ids;
  }

  // Copies the given list of check-ids to be excluded, unless |exclude_by_default| is true, in
  // which case, all checks are excluded if not explicitly included.
  void set_excluded_checks(const std::set<std::string>& excluded_check_ids) {
    excluded_check_ids_ = excluded_check_ids;
  }

  // Calling Lint() invokes the callbacks for elements
  // of the given |SourceFile|. If a check fails, the callback generates a
  // |Finding| and adds it to the given Findings (vector of Finding).
  // Lint() is single-threaded, and modifies state of the |Linter| class
  // as it evaluates a single file at a time.
  //
  // * parsed_source - The abstract syntax tree (AST) returned from the FIDL Parser.
  // * findings - a std::list of Finding objects (ordered by filename and location) to add
  //   additional Finding objects to, if triggered for a check. The list may or may not be
  //   empty.
  // * excluded_checks_not_found (optional) - If not nullptr, excluded_checks_not_found is a
  //   pointer to the caller's std::set of check-ids that were
  //   excluded and have not yet been removed via a pevious invocation of Lint() (if any). If this
  //   set is not empty, and a matching check-id is triggered, remove the check-id. An error
  //   status will be returned by the linter program, after all files have been linted, if any
  //   excluded check IDs remain in this set.
  //
  // Returns true if no new findings were generated.
  bool Lint(std::unique_ptr<raw::File> const& parsed_source, Findings* findings,
            std::set<std::string>* excluded_checks_not_found);

  bool Lint(std::unique_ptr<raw::File> const& parsed_source, Findings* findings) {
    return Lint(parsed_source, findings, nullptr);
  }

 private:
  // Holds function pointers for an identify case type. For example,
  // for "UpperCamelCase" type, |matches| points to is_upper_camel_case()
  // and |convert| points to to_upper_camel_case().
  struct CaseType {
    fit::function<bool(std::string)> matches;
    fit::function<std::string(std::string)> convert;
  };

  // Holds information about a nesting context in a FIDL file, for checks
  // that must compare information about the context with information about
  // a nested entity. The outer-most context is the FIDL file itself
  // (including the file's declared library name). Contexts nested in a
  // file's context include type definitions with nested entities, such as
  // enum, bits, struct, table, and union.
  class Context {
   public:
    struct RepeatsContextNames;

    Context(std::string type, std::string id, CheckDef context_check)
        : type_(type), id_(id), context_check_(context_check) {}

    // Enables move construction and assignment
    Context(Context&& rhs) = default;
    Context& operator=(Context&&) = default;

    // no copy or assign (move-only or pass by reference)
    Context(const Context&) = delete;
    Context& operator=(const Context&) = delete;

    std::string type() const { return type_; }

    std::string id() const { return id_; }

    // A |vector| of information about potential violations of the FIDL rubric
    // rule that prohibits repeating names from the outer type or library.
    // Exceptions to this rule cannot be determined until all nested identifiers
    // are reviewed, so this vector saves the required information until that
    // time.
    std::vector<RepeatsContextNames>& name_repeaters() { return name_repeaters_; }

    const std::set<std::string>& words() {
      if (words_.empty()) {
        auto words = utils::id_to_words(id_);
        words_.insert(words.begin(), words.end());
      }
      return words_;
    }

    const CheckDef& context_check() const { return context_check_; }

    template <typename... Args>
    void AddRepeatsContextNames(Args&&... args) {
      name_repeaters_.emplace_back(args...);
    }

    // Stores minimum information needed to construct a |Finding| if a
    // nested identifier repeats names from one of its contexts.
    // Determination is deferred until all nested identifiers are evaluated
    // because some cases of repeated names are allowed if the repeated
    // names help differentiate two identifiers that represent different
    // parts of the concept represented by the context identifier.
    struct RepeatsContextNames {
      RepeatsContextNames(std::string a_type, SourceSpan a_span, std::set<std::string> a_repeats)
          : type(std::move(a_type)), span(a_span), repeats(std::move(a_repeats)) {}

      const std::string type;
      const SourceSpan span;
      const std::set<std::string> repeats;
    };

   private:
    std::string type_;
    std::string id_;
    std::set<std::string> words_;
    CheckDef context_check_;
    std::vector<RepeatsContextNames> name_repeaters_;
  };

  const std::set<std::string>& permitted_library_prefixes() const;
  std::string kPermittedLibraryPrefixesas_string() const;

  CheckDef DefineCheck(std::string check_id, std::string message_template);

  Finding* AddFinding(SourceSpan source_span, std::string check_id, std::string message);

  const Finding* AddFinding(SourceSpan span, const CheckDef& check,
                            Substitutions substitutions = {}, std::string suggestion_template = "",
                            std::string replacement_template = "");

  template <typename SourceElementSubtypeRefOrPtr>
  const Finding* AddFinding(const SourceElementSubtypeRefOrPtr& element, const CheckDef& check,
                            Substitutions substitutions = {}, std::string suggestion_template = "",
                            std::string replacement_template = "");

  const Finding* AddRepeatedNameFinding(const Context& context,
                                        const Context::RepeatsContextNames& name_repeater);

  bool CurrentLibraryIsPlatformSourceLibrary();
  bool CurrentFileIsInPlatformSourceTree();

  // Initialization and checks at the start of a new file. The |Linter|
  // can be called multiple times with many different files.
  void NewFile(const raw::File& element);

  // If a finding was added, return a pointer to that finding.
  const Finding* CheckCase(std::string type, const std::unique_ptr<raw::Identifier>& identifier,
                           const CheckDef& check_def, const CaseType& case_type);

  // CheckRepeatedName() does not add Finding objects immediately. It checks for
  // potential violations, but must wait until ExitContext() so the potential
  // violation can be compared to its peers.
  void CheckRepeatedName(std::string type, const std::unique_ptr<raw::Identifier>& id);

  template <typename... Args>
  void EnterContext(Args&&... args) {
    context_stack_.emplace_front(args...);
  }

  // Pops the context stack. If any contained types repeat names from the
  // context, this function compares the nested identifiers with each other.
  // If two nested identifiers repeat different names from the context,
  // assume the repeated names were necessary in order to disambiguate the
  // concepts represented by each of the nested entities. If not, add Finding
  // objects for violating the repeated name rule.
  void ExitContext();

  std::string GetCopyrightSuggestion();
  void AddInvalidCopyrightFinding(SourceSpan span);
  void CheckInvalidCopyright(SourceSpan span, std::string line_comment, std::string line_to_match);
  bool CopyrightCheckIsComplete();

  std::string MakeCopyrightBlock();

  // All check types created in during |Linter| construction. The |std::set|
  // ensures each CheckDef has a unique |id|, and an iterator will traverse
  // the set in lexicographical order.
  // Must be defined before constant checks.
  std::set<CheckDef> checks_;

  // const variables not trivially destructible (static storage is forbidden)
  // (https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables)
  const CheckDef kLibraryNameDepthCheck;
  const CheckDef kLibraryNameComponentCheck;
  const CheckDef kRepeatsLibraryNameCheck;
  const CheckDef kLibraryPrefixCheck;
  const CheckDef kInvalidCopyrightCheck;

  const std::vector<std::string> kCopyrightLines;
  const std::string kCopyrightBlock;
  const std::string kDocAttribute;
  const std::regex kYearRegex;
  const std::regex kDocCommentRegex;
  const std::regex kDisallowedLibraryComponentRegex;

  const std::set<std::string> kPermittedLibraryPrefixes;
  const std::set<std::string> kStopWords;

  std::deque<Context> context_stack_;

  size_t line_comments_checked_ = 0;

  // Set to true for the first line that does not match the standard
  // Copyright block (if checked) so subsequent lines do not have to
  // be checked. (Prevents duplicate findings.)
  bool added_invalid_copyright_finding_ = false;

  // If good copyright lines
  size_t good_copyright_lines_found_ = 0;

  // 4 digits assumed to be the intended copyright date.
  std::string copyright_date_;

  // true if a const declaration was entered, and not yet exited.
  bool in_const_declaration_ = false;

  // The first name in the FIDL library declaration; for example, for:
  //   library fidl.types;
  // |library_prefix_| will be "fidl"
  std::string library_prefix_;
  bool library_is_platform_source_library_;

  std::string filename_;
  bool file_is_in_platform_source_tree_;

  enum class LintStyle {
    IpcStyle,
    CStyle,
  };
  LintStyle lint_style_;

  LintingTreeCallbacks callbacks_;

  // Case type functions used by CheckCase().
  CaseType lower_snake_{utils::is_lower_snake_case, utils::to_lower_snake_case};
  CaseType upper_snake_{utils::is_upper_snake_case, utils::to_upper_snake_case};
  CaseType upper_camel_{utils::is_upper_camel_case, utils::to_upper_camel_case};

  // In IpcStyle, bits, protocols, protocol methods, structs, tables, unions,
  // and enums use UpperCamelCase. In CStyle used for syscalls, they
  // use lower_camel_case. This member is set in NewFile once the style that's
  // being used has been determined.
  CheckDef invalid_case_for_decl_name_{"", TemplateString()};
  const CheckDef& invalid_case_for_decl_name() const { return invalid_case_for_decl_name_; }

  const CaseType& decl_case_type_for_style() const {
    switch (lint_style_) {
      case LintStyle::IpcStyle:
        return upper_camel_;
      case LintStyle::CStyle:
        return lower_snake_;
    }
  }

  bool exclude_by_default_ = false;
  std::set<std::string> included_check_ids_;
  std::set<std::string> excluded_check_ids_;

  using FindingPtr = std::unique_ptr<Finding>;

  // Compare type provides the function for ordering elements in the set, and
  // ensuring elements are set-wise unique. The current assumption is that no
  // two findings from the same subcategory at the same location are expected.
  // By including both source span and subcategory, all expected Findings
  // will be unique, and any Finding added with the same location and
  // subcategory as another will be considered a bug.
  struct FindingPtrCompare {
    // Return true if lhs < rhs.
    bool operator()(const FindingPtr& lhs, const FindingPtr& rhs) const {
      return lhs->span() < rhs->span() ||
             (lhs->span() == rhs->span() && lhs->subcategory() < rhs->subcategory());
    }
  };

  // An ordered collection of |std::unique_ptr| to |Finding| objects,
  // populated only for the duration of the Visit(), to lint a given FIDL
  // file.
  //
  // Some lint checks can only be assessed after processing more of the FIDL
  // (for example, "name-repeats-enclosing-type-name" checks cannot be added
  // until all members of the enclosing type are available). Other checks on
  // the same members will be added as they are encountered. Since |Finding|
  // objects are collected out of source order, an ordered collecttion
  // ensures |Finding| objects are in sorted order.
  //
  // |Finding| objects must be returned in source order (filename, starting
  // character, and ending character).
  //
  // |Finding| objects are sorted by SourceSpan, with additional criteria
  // to sort multiple findings for the same source element. If a Finding is
  // added to an ordered collection that does not allow duplicates, and the
  // sort criteria is not specific enough to avoid a key collision, an
  // assertion error will halt the program, to be resolved either by adding
  // additional sort criteriea or changing the Finding objects to ensure
  // uinqueness.
  //
  // When the Visit() is over, the |Finding| objects are transferred, in order
  // (by filename and source location of each finding, with any duplicates
  // also included in the order they were discovered/added) into the |Findings|
  // list passed into the Lint() method, and |current_findings_| is cleared.
  std::set<FindingPtr, FindingPtrCompare> current_findings_;
};

}  // namespace linter
}  // namespace fidl
#endif  // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_LINTER_H_
