//===--- IdentifierNamingCheck.h - clang-tidy -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H

#include "../utils/RenamerClangTidyCheck.h"
#include "llvm/ADT/Optional.h"
namespace clang {
namespace tidy {
namespace readability {

enum StyleKind : int;

/// Checks for identifiers naming style mismatch.
///
/// This check will try to enforce coding guidelines on the identifiers naming.
/// It supports `lower_case`, `UPPER_CASE`, `camelBack` and `CamelCase` casing
/// and tries to convert from one to another if a mismatch is detected.
///
/// It also supports a fixed prefix and suffix that will be prepended or
/// appended to the identifiers, regardless of the casing.
///
/// Many configuration options are available, in order to be able to create
/// different rules for different kind of identifier. In general, the
/// rules are falling back to a more generic rule if the specific case is not
/// configured.
class IdentifierNamingCheck final : public RenamerClangTidyCheck {
public:
  IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context);
  ~IdentifierNamingCheck();

  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;

  enum CaseType {
    CT_AnyCase = 0,
    CT_LowerCase,
    CT_CamelBack,
    CT_UpperCase,
    CT_CamelCase,
    CT_CamelSnakeCase,
    CT_CamelSnakeBack
  };

  enum HungarianPrefixType {
    HPT_Off = 0,
    HPT_On,
    HPT_LowerCase,
    HPT_CamelCase,
  };

  struct HungarianNotationOption {
    HungarianNotationOption() : HPType(HungarianPrefixType::HPT_Off) {}

    llvm::Optional<CaseType> Case;
    HungarianPrefixType HPType;
    llvm::StringMap<std::string> General;
    llvm::StringMap<std::string> CString;
    llvm::StringMap<std::string> PrimitiveType;
    llvm::StringMap<std::string> UserDefinedType;
    llvm::StringMap<std::string> DerivedType;
  };

  struct NamingStyle {
    NamingStyle() = default;

    NamingStyle(llvm::Optional<CaseType> Case, const std::string &Prefix,
                const std::string &Suffix, const std::string &IgnoredRegexpStr,
                HungarianPrefixType HPType);
    NamingStyle(const NamingStyle &O) = delete;
    NamingStyle &operator=(NamingStyle &&O) = default;
    NamingStyle(NamingStyle &&O) = default;

    llvm::Optional<CaseType> Case;
    std::string Prefix;
    std::string Suffix;
    // Store both compiled and non-compiled forms so original value can be
    // serialized
    llvm::Regex IgnoredRegexp;
    std::string IgnoredRegexpStr;

    HungarianPrefixType HPType;
  };

  struct HungarianNotation {
  public:
    bool checkOptionValid(int StyleKindIndex) const;
    bool isOptionEnabled(StringRef OptionKey,
                         const llvm::StringMap<std::string> &StrMap) const;
    void loadDefaultConfig(
        IdentifierNamingCheck::HungarianNotationOption &HNOption) const;
    void loadFileConfig(
        const ClangTidyCheck::OptionsView &Options,
        IdentifierNamingCheck::HungarianNotationOption &HNOption) const;

    bool removeDuplicatedPrefix(
        SmallVector<StringRef, 8> &Words,
        const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;

    std::string getPrefix(
        const Decl *D,
        const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;

    std::string getDataTypePrefix(
        StringRef TypeName, const NamedDecl *ND,
        const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;

    std::string getClassPrefix(
        const CXXRecordDecl *CRD,
        const IdentifierNamingCheck::HungarianNotationOption &HNOption) const;

    std::string getEnumPrefix(const EnumConstantDecl *ECD) const;
    std::string getDeclTypeName(const NamedDecl *ND) const;
  };

  struct FileStyle {
    FileStyle() : IsActive(false), IgnoreMainLikeFunctions(false) {}
    FileStyle(SmallVectorImpl<Optional<NamingStyle>> &&Styles,
              HungarianNotationOption HNOption, bool IgnoreMainLike)
        : Styles(std::move(Styles)), HNOption(std::move(HNOption)),
          IsActive(true), IgnoreMainLikeFunctions(IgnoreMainLike) {}

    ArrayRef<Optional<NamingStyle>> getStyles() const {
      assert(IsActive);
      return Styles;
    }

    const HungarianNotationOption &getHNOption() const {
      assert(IsActive);
      return HNOption;
    }

    bool isActive() const { return IsActive; }
    bool isIgnoringMainLikeFunction() const { return IgnoreMainLikeFunctions; }

  private:
    SmallVector<Optional<NamingStyle>, 0> Styles;
    HungarianNotationOption HNOption;
    bool IsActive;
    bool IgnoreMainLikeFunctions;
  };

  IdentifierNamingCheck::FileStyle
  getFileStyleFromOptions(const ClangTidyCheck::OptionsView &Options) const;

  bool
  matchesStyle(StringRef Type, StringRef Name,
               const IdentifierNamingCheck::NamingStyle &Style,
               const IdentifierNamingCheck::HungarianNotationOption &HNOption,
               const NamedDecl *Decl) const;

  std::string
  fixupWithCase(StringRef Type, StringRef Name, const Decl *D,
                const IdentifierNamingCheck::NamingStyle &Style,
                const IdentifierNamingCheck::HungarianNotationOption &HNOption,
                IdentifierNamingCheck::CaseType Case) const;

  std::string
  fixupWithStyle(StringRef Type, StringRef Name,
                 const IdentifierNamingCheck::NamingStyle &Style,
                 const IdentifierNamingCheck::HungarianNotationOption &HNOption,
                 const Decl *D) const;

  StyleKind findStyleKind(
      const NamedDecl *D,
      ArrayRef<llvm::Optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
      bool IgnoreMainLikeFunctions) const;

  llvm::Optional<RenamerClangTidyCheck::FailureInfo> getFailureInfo(
      StringRef Type, StringRef Name, const NamedDecl *ND,
      SourceLocation Location,
      ArrayRef<llvm::Optional<IdentifierNamingCheck::NamingStyle>> NamingStyles,
      const IdentifierNamingCheck::HungarianNotationOption &HNOption,
      StyleKind SK, const SourceManager &SM, bool IgnoreFailedSplit) const;

  bool isParamInMainLikeFunction(const ParmVarDecl &ParmDecl,
                                 bool IncludeMainLike) const;

private:
  llvm::Optional<FailureInfo>
  getDeclFailureInfo(const NamedDecl *Decl,
                     const SourceManager &SM) const override;
  llvm::Optional<FailureInfo>
  getMacroFailureInfo(const Token &MacroNameTok,
                      const SourceManager &SM) const override;
  DiagInfo getDiagInfo(const NamingCheckId &ID,
                       const NamingCheckFailure &Failure) const override;

  const FileStyle &getStyleForFile(StringRef FileName) const;

  /// Stores the style options as a vector, indexed by the specified \ref
  /// StyleKind, for a given directory.
  mutable llvm::StringMap<FileStyle> NamingStylesCache;
  FileStyle *MainFileStyle;
  ClangTidyContext *Context;
  const StringRef CheckName;
  const bool GetConfigPerFile;
  const bool IgnoreFailedSplit;
  HungarianNotation HungarianNotation;
};

} // namespace readability
template <>
struct OptionEnumMapping<readability::IdentifierNamingCheck::CaseType> {
  static llvm::ArrayRef<
      std::pair<readability::IdentifierNamingCheck::CaseType, StringRef>>
  getEnumMapping();
};
} // namespace tidy
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
