///===-- Representation.h - ClangDoc Representation -------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the internal representations of different declaration
// types for the clang-doc tool.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H

#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Tooling/Execution.h"
#include "llvm/ADT/SmallVector.h"
#include <array>
#include <optional>
#include <string>

namespace clang {
namespace doc {

// SHA1'd hash of a USR.
using SymbolID = std::array<uint8_t, 20>;

constexpr SymbolID GlobalNamespaceID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

struct BaseRecordInfo;
struct EnumInfo;
struct FunctionInfo;
struct Info;
struct TypedefInfo;
struct ConceptInfo;
struct VarInfo;

enum class InfoType {
  IT_default,
  IT_namespace,
  IT_record,
  IT_function,
  IT_enum,
  IT_typedef,
  IT_concept,
  IT_variable,
  IT_friend
};

enum class CommentKind {
  CK_FullComment,
  CK_ParagraphComment,
  CK_TextComment,
  CK_InlineCommandComment,
  CK_HTMLStartTagComment,
  CK_HTMLEndTagComment,
  CK_BlockCommandComment,
  CK_ParamCommandComment,
  CK_TParamCommandComment,
  CK_VerbatimBlockComment,
  CK_VerbatimBlockLineComment,
  CK_VerbatimLineComment,
  CK_Unknown
};

CommentKind stringToCommentKind(llvm::StringRef KindStr);
llvm::StringRef commentKindToString(CommentKind Kind);

// A representation of a parsed comment.
struct CommentInfo {
  CommentInfo() = default;
  CommentInfo(CommentInfo &Other) = delete;
  CommentInfo(CommentInfo &&Other) = default;
  CommentInfo &operator=(CommentInfo &&Other) = default;

  bool operator==(const CommentInfo &Other) const;

  // This operator is used to sort a vector of CommentInfos.
  // No specific order (attributes more important than others) is required. Any
  // sort is enough, the order is only needed to call std::unique after sorting
  // the vector.
  bool operator<(const CommentInfo &Other) const;

  std::vector<std::unique_ptr<CommentInfo>>
      Children;              // List of child comments for this CommentInfo.
  SmallString<8> Direction;  // Parameter direction (for (T)ParamCommand).
  SmallString<16> Name;      // Name of the comment (for Verbatim and HTML).
  SmallString<16> ParamName; // Parameter name (for (T)ParamCommand).
  SmallString<16> CloseName; // Closing tag name (for VerbatimBlock).
  SmallString<64> Text;      // Text of the comment.
  llvm::SmallVector<SmallString<16>, 4>
      AttrKeys; // List of attribute keys (for HTML).
  llvm::SmallVector<SmallString<16>, 4>
      AttrValues; // List of attribute values for each key (for HTML).
  llvm::SmallVector<SmallString<16>, 4>
      Args; // List of arguments to commands (for InlineCommand).
  CommentKind Kind = CommentKind::
      CK_Unknown; // Kind of comment (FullComment, ParagraphComment,
                  // TextComment, InlineCommandComment, HTMLStartTagComment,
                  // HTMLEndTagComment, BlockCommandComment,
                  // ParamCommandComment, TParamCommandComment,
                  // VerbatimBlockComment, VerbatimBlockLineComment,
                  // VerbatimLineComment).
  bool SelfClosing = false; // Indicates if tag is self-closing (for HTML).
  bool Explicit = false;    // Indicates if the direction of a param is explicit
                            // (for (T)ParamCommand).
};

struct Reference {
  // This variant (that takes no qualified name parameter) uses the Name as the
  // QualName (very useful in unit tests to reduce verbosity). This can't use an
  // empty string to indicate the default because we need to accept the empty
  // string as a valid input for the global namespace (it will have
  // "GlobalNamespace" as the name, but an empty QualName).
  Reference(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
            InfoType IT = InfoType::IT_default)
      : USR(USR), RefType(IT), Name(Name), QualName(Name) {}
  Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
            StringRef Path = StringRef())
      : USR(USR), RefType(IT), Name(Name), QualName(QualName), Path(Path) {}
  Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
            StringRef Path, SmallString<16> DocumentationFileName)
      : USR(USR), RefType(IT), Name(Name), QualName(QualName), Path(Path),
        DocumentationFileName(DocumentationFileName) {}

  bool operator==(const Reference &Other) const {
    return std::tie(USR, Name, QualName, RefType) ==
           std::tie(Other.USR, Other.Name, QualName, Other.RefType);
  }

  bool mergeable(const Reference &Other);
  void merge(Reference &&I);
  bool operator<(const Reference &Other) const { return Name < Other.Name; }

  /// Returns the path for this Reference relative to CurrentPath.
  llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;

  /// Returns the basename that should be used for this Reference.
  llvm::SmallString<16> getFileBaseName() const;

  SymbolID USR = SymbolID(); // Unique identifier for referenced decl

  InfoType RefType = InfoType::IT_default; // Indicates the type of this
                                           // Reference (namespace, record,
                                           // function, enum, default).

  // Name of type (possibly unresolved). Not including namespaces or template
  // parameters (so for a std::vector<int> this would be "vector"). See also
  // QualName.
  SmallString<16> Name;

  // Full qualified name of this type, including namespaces and template
  // parameter (for example this could be "std::vector<int>"). Contrast to
  // Name.
  SmallString<16> QualName;

  // Path of directory where the clang-doc generated file will be saved
  // (possibly unresolved)
  llvm::SmallString<128> Path;
  SmallString<16> DocumentationFileName;
};

// Holds the children of a record or namespace.
struct ScopeChildren {
  // Namespaces and Records are references because they will be properly
  // documented in their own info, while the entirety of Functions and Enums are
  // included here because they should not have separate documentation from
  // their scope.
  //
  // Namespaces are not syntactically valid as children of records, but making
  // this general for all possible container types reduces code complexity.
  std::vector<Reference> Namespaces;
  std::vector<Reference> Records;
  std::vector<FunctionInfo> Functions;
  std::vector<EnumInfo> Enums;
  std::vector<TypedefInfo> Typedefs;
  std::vector<ConceptInfo> Concepts;
  std::vector<VarInfo> Variables;

  void sort();
};

// A base struct for TypeInfos
struct TypeInfo {
  TypeInfo() = default;
  TypeInfo(const Reference &R) : Type(R) {}

  // Convenience constructor for when there is no symbol ID or info type
  // (normally used for built-in types in tests).
  TypeInfo(StringRef Name, StringRef Path = StringRef())
      : Type(SymbolID(), Name, InfoType::IT_default, Name, Path) {}

  bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }

  Reference Type; // Referenced type in this info.

  bool IsTemplate = false;
  bool IsBuiltIn = false;
};

// Represents one template parameter.
//
// This is a very simple serialization of the text of the source code of the
// template parameter. It is saved in a struct so there is a place to add the
// name and default values in the future if needed.
struct TemplateParamInfo {
  TemplateParamInfo() = default;
  explicit TemplateParamInfo(StringRef Contents) : Contents(Contents) {}

  // The literal contents of the code for that specifies this template parameter
  // for this declaration. Typical values will be "class T" and
  // "typename T = int".
  SmallString<16> Contents;
};

struct TemplateSpecializationInfo {
  // Indicates the declaration that this specializes.
  SymbolID SpecializationOf;

  // Template parameters applying to the specialized record/function.
  std::vector<TemplateParamInfo> Params;
};

struct ConstraintInfo {
  ConstraintInfo() = default;
  ConstraintInfo(SymbolID USR, StringRef Name)
      : ConceptRef(USR, Name, InfoType::IT_concept) {}
  Reference ConceptRef;

  SmallString<16> ConstraintExpr;
};

// Records the template information for a struct or function that is a template
// or an explicit template specialization.
struct TemplateInfo {
  // May be empty for non-partial specializations.
  std::vector<TemplateParamInfo> Params;

  // Set when this is a specialization of another record/function.
  std::optional<TemplateSpecializationInfo> Specialization;
  std::vector<ConstraintInfo> Constraints;
};

// Info for field types.
struct FieldTypeInfo : public TypeInfo {
  FieldTypeInfo() = default;
  FieldTypeInfo(const TypeInfo &TI, StringRef Name = StringRef(),
                StringRef DefaultValue = StringRef())
      : TypeInfo(TI), Name(Name), DefaultValue(DefaultValue) {}

  bool operator==(const FieldTypeInfo &Other) const {
    return std::tie(Type, Name, DefaultValue) ==
           std::tie(Other.Type, Other.Name, Other.DefaultValue);
  }

  SmallString<16> Name; // Name associated with this info.

  // When used for function parameters, contains the string representing the
  // expression of the default value, if any.
  SmallString<16> DefaultValue;
};

// Info for member types.
struct MemberTypeInfo : public FieldTypeInfo {
  MemberTypeInfo() = default;
  MemberTypeInfo(const TypeInfo &TI, StringRef Name, AccessSpecifier Access,
                 bool IsStatic = false)
      : FieldTypeInfo(TI, Name), Access(Access), IsStatic(IsStatic) {}

  bool operator==(const MemberTypeInfo &Other) const {
    return std::tie(Type, Name, Access, IsStatic, Description) ==
           std::tie(Other.Type, Other.Name, Other.Access, Other.IsStatic,
                    Other.Description);
  }

  std::vector<CommentInfo> Description;

  // Access level associated with this info (public, protected, private, none).
  // AS_public is set as default because the bitcode writer requires the enum
  // with value 0 to be used as the default.
  // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
  AccessSpecifier Access = AccessSpecifier::AS_public;
  bool IsStatic = false;
};

struct Location {
  Location(int StartLineNumber = 0, int EndLineNumber = 0,
           StringRef Filename = StringRef(), bool IsFileInRootDir = false)
      : Filename(Filename), StartLineNumber(StartLineNumber),
        EndLineNumber(EndLineNumber), IsFileInRootDir(IsFileInRootDir) {}

  bool operator==(const Location &Other) const {
    return std::tie(StartLineNumber, EndLineNumber, Filename) ==
           std::tie(Other.StartLineNumber, Other.EndLineNumber, Other.Filename);
  }

  bool operator!=(const Location &Other) const { return !(*this == Other); }

  // This operator is used to sort a vector of Locations.
  // No specific order (attributes more important than others) is required. Any
  // sort is enough, the order is only needed to call std::unique after sorting
  // the vector.
  bool operator<(const Location &Other) const {
    return std::tie(StartLineNumber, EndLineNumber, Filename) <
           std::tie(Other.StartLineNumber, Other.EndLineNumber, Other.Filename);
  }

  SmallString<32> Filename;
  int StartLineNumber = 0;
  int EndLineNumber = 0;
  bool IsFileInRootDir = false;
};

/// A base struct for Infos.
struct Info {
  Info(InfoType IT = InfoType::IT_default, SymbolID USR = SymbolID(),
       StringRef Name = StringRef(), StringRef Path = StringRef())
      : Path(Path), Name(Name), USR(USR), IT(IT) {}

  Info(const Info &Other) = delete;
  Info(Info &&Other) = default;
  virtual ~Info() = default;

  Info &operator=(Info &&Other) = default;

  void mergeBase(Info &&I);
  bool mergeable(const Info &Other);

  llvm::SmallString<16> extractName() const;

  /// Returns the file path for this Info relative to CurrentPath.
  llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;

  /// Returns the basename that should be used for this Info.
  llvm::SmallString<16> getFileBaseName() const;

  // Path of directory where the clang-doc generated file will be saved.
  llvm::SmallString<128> Path;

  // Unqualified name of the decl.
  SmallString<16> Name;

  // The name used for the file that this info is documented in.
  // In the JSON generator, infos are documented in files with mangled names.
  // Thus, we keep track of the physical filename for linking purposes.
  SmallString<16> DocumentationFileName;

  // List of parent namespaces for this decl.
  llvm::SmallVector<Reference, 4> Namespace;

  // Unique identifier for the decl described by this Info.
  SymbolID USR = SymbolID();

  // InfoType of this particular Info.
  InfoType IT = InfoType::IT_default;

  // Comment description of this decl.
  std::vector<CommentInfo> Description;
};

// Info for namespaces.
struct NamespaceInfo : public Info {
  NamespaceInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
                StringRef Path = StringRef());

  void merge(NamespaceInfo &&I);

  ScopeChildren Children;
};

// Info for symbols.
struct SymbolInfo : public Info {
  SymbolInfo(InfoType IT, SymbolID USR = SymbolID(),
             StringRef Name = StringRef(), StringRef Path = StringRef())
      : Info(IT, USR, Name, Path) {}

  void merge(SymbolInfo &&I);

  bool operator<(const SymbolInfo &Other) const {
    // Sort by declaration location since we want the doc to be
    // generated in the order of the source code.
    // If the declaration location is the same, or not present
    // we sort by defined location otherwise fallback to the extracted name
    if (Loc.size() > 0 && Other.Loc.size() > 0 && Loc[0] != Other.Loc[0])
      return Loc[0] < Other.Loc[0];

    if (DefLoc && Other.DefLoc && *DefLoc != *Other.DefLoc)
      return *DefLoc < *Other.DefLoc;

    return extractName() < Other.extractName();
  }

  std::optional<Location> DefLoc;     // Location where this decl is defined.
  llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared.
  SmallString<16> MangledName;
  bool IsStatic = false;
};

struct FriendInfo : SymbolInfo {
  FriendInfo() : SymbolInfo(InfoType::IT_friend) {}
  FriendInfo(SymbolID USR) : SymbolInfo(InfoType::IT_friend, USR) {}
  FriendInfo(const InfoType IT, const SymbolID &USR,
             const StringRef Name = StringRef())
      : SymbolInfo(IT, USR, Name) {}
  bool mergeable(const FriendInfo &Other);
  void merge(FriendInfo &&Other);

  Reference Ref;
  std::optional<TemplateInfo> Template;
  std::optional<TypeInfo> ReturnType;
  std::optional<SmallVector<FieldTypeInfo, 4>> Params;
  bool IsClass = false;
};

struct VarInfo : SymbolInfo {
  VarInfo() : SymbolInfo(InfoType::IT_variable) {}
  explicit VarInfo(SymbolID USR) : SymbolInfo(InfoType::IT_variable, USR) {}

  void merge(VarInfo &&I);

  TypeInfo Type;
};

// TODO: Expand to allow for documenting templating and default args.
// Info for functions.
struct FunctionInfo : public SymbolInfo {
  FunctionInfo(SymbolID USR = SymbolID())
      : SymbolInfo(InfoType::IT_function, USR) {}

  void merge(FunctionInfo &&I);

  Reference Parent;
  TypeInfo ReturnType;
  llvm::SmallVector<FieldTypeInfo, 4> Params;
  SmallString<256> Prototype;

  // When present, this function is a template or specialization.
  std::optional<TemplateInfo> Template;

  // Access level for this method (public, private, protected, none).
  // AS_public is set as default because the bitcode writer requires the enum
  // with value 0 to be used as the default.
  // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
  AccessSpecifier Access = AccessSpecifier::AS_public;

  bool IsMethod = false;
};

// TODO: Expand to allow for documenting templating, inheritance access,
// friend classes
// Info for types.
struct RecordInfo : public SymbolInfo {
  RecordInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
             StringRef Path = StringRef());

  void merge(RecordInfo &&I);

  // Type of this record (struct, class, union, interface).
  TagTypeKind TagType = TagTypeKind::Struct;

  // Indicates if the record was declared using a typedef. Things like anonymous
  // structs in a typedef:
  //   typedef struct { ... } foo_t;
  // are converted into records with the typedef as the Name + this flag set.
  bool IsTypeDef = false;

  // When present, this record is a template or specialization.
  std::optional<TemplateInfo> Template;

  llvm::SmallVector<MemberTypeInfo, 4>
      Members;                             // List of info about record members.
  llvm::SmallVector<Reference, 4> Parents; // List of base/parent records
                                           // (does not include virtual
                                           // parents).
  llvm::SmallVector<Reference, 4>
      VirtualParents; // List of virtual base/parent records.

  std::vector<BaseRecordInfo>
      Bases; // List of base/parent records; this includes inherited methods and
             // attributes

  std::vector<FriendInfo> Friends;

  ScopeChildren Children;
};

// Info for typedef and using statements.
struct TypedefInfo : public SymbolInfo {
  TypedefInfo(SymbolID USR = SymbolID())
      : SymbolInfo(InfoType::IT_typedef, USR) {}

  void merge(TypedefInfo &&I);

  TypeInfo Underlying;

  // Only type aliases can be templates.
  std::optional<TemplateInfo> Template;

  // Underlying type declaration
  SmallString<16> TypeDeclaration;

  // Indicates if this is a new C++ "using"-style typedef:
  //   using MyVector = std::vector<int>
  // False means it's a C-style typedef:
  //   typedef std::vector<int> MyVector;
  bool IsUsing = false;
};

struct BaseRecordInfo : public RecordInfo {
  BaseRecordInfo();
  BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, bool IsVirtual,
                 AccessSpecifier Access, bool IsParent);

  // Access level associated with this inherited info (public, protected,
  // private).
  AccessSpecifier Access = AccessSpecifier::AS_public;
  // Indicates if base corresponds to a virtual inheritance
  bool IsVirtual = false;
  bool IsParent = false; // Indicates if this base is a direct parent
};

// Information for a single possible value of an enumeration.
struct EnumValueInfo {
  explicit EnumValueInfo(StringRef Name = StringRef(),
                         StringRef Value = StringRef("0"),
                         StringRef ValueExpr = StringRef())
      : Name(Name), Value(Value), ValueExpr(ValueExpr) {}

  bool operator==(const EnumValueInfo &Other) const {
    return std::tie(Name, Value, ValueExpr) ==
           std::tie(Other.Name, Other.Value, Other.ValueExpr);
  }

  SmallString<16> Name;

  // The computed value of the enumeration constant. This could be the result of
  // evaluating the ValueExpr, or it could be automatically generated according
  // to C rules.
  SmallString<16> Value;

  // Stores the user-supplied initialization expression for this enumeration
  // constant. This will be empty for implicit enumeration values.
  SmallString<16> ValueExpr;

  /// Comment description of this field.
  std::vector<CommentInfo> Description;
};

// TODO: Expand to allow for documenting templating.
// Info for types.
struct EnumInfo : public SymbolInfo {
  EnumInfo() : SymbolInfo(InfoType::IT_enum) {}
  EnumInfo(SymbolID USR) : SymbolInfo(InfoType::IT_enum, USR) {}

  void merge(EnumInfo &&I);

  // Indicates whether this enum is scoped (e.g. enum class).
  bool Scoped = false;

  // Set to nonempty to the type when this is an explicitly typed enum. For
  //   enum Foo : short { ... };
  // this will be "short".
  std::optional<TypeInfo> BaseType;

  llvm::SmallVector<EnumValueInfo, 4> Members; // List of enum members.
};

struct ConceptInfo : public SymbolInfo {
  ConceptInfo() : SymbolInfo(InfoType::IT_concept) {}
  ConceptInfo(SymbolID USR) : SymbolInfo(InfoType::IT_concept, USR) {}

  void merge(ConceptInfo &&I);

  bool IsType;
  TemplateInfo Template;
  SmallString<16> ConstraintExpression;
};

struct Index : public Reference {
  Index() = default;
  Index(StringRef Name) : Reference(SymbolID(), Name) {}
  Index(StringRef Name, StringRef JumpToSection)
      : Reference(SymbolID(), Name), JumpToSection(JumpToSection) {}
  Index(SymbolID USR, StringRef Name, InfoType IT, StringRef Path)
      : Reference(USR, Name, IT, Name, Path) {}
  // This is used to look for a USR in a vector of Indexes using std::find
  bool operator==(const SymbolID &Other) const { return USR == Other; }
  bool operator<(const Index &Other) const;

  std::optional<SmallString<16>> JumpToSection;
  std::vector<Index> Children;

  void sort();
};

// TODO: Add functionality to include separate markdown pages.

// A standalone function to call to merge a vector of infos into one.
// This assumes that all infos in the vector are of the same type, and will fail
// if they are different.
llvm::Expected<std::unique_ptr<Info>>
mergeInfos(std::vector<std::unique_ptr<Info>> &Values);

struct ClangDocContext {
  ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
                  bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
                  StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix,
                  StringRef Base, std::vector<std::string> UserStylesheets,
                  clang::DiagnosticsEngine &Diags, bool FTimeTrace = false);
  tooling::ExecutionContext *ECtx;
  std::string ProjectName;  // Name of project clang-doc is documenting.
  std::string OutDirectory; // Directory for outputting generated files.
  std::string SourceRoot;   // Directory where processed files are stored. Links
                            // to definition locations will only be generated if
                            // the file is in this dir.
  // URL of repository that hosts code used for links to definition locations.
  std::optional<std::string> RepositoryUrl;
  // Prefix of line code for repository.
  std::optional<std::string> RepositoryLinePrefix;
  // Path of CSS stylesheets that will be copied to OutDirectory and used to
  // style all HTML files.
  std::vector<std::string> UserStylesheets;
  // JavaScript files that will be imported in all HTML files.
  std::vector<std::string> JsScripts;
  // Base directory for remote repositories.
  StringRef Base;
  // Maps mustache template types to specific mustache template files.
  // Ex.    comment-template -> /path/to/comment-template.mustache
  llvm::StringMap<std::string> MustacheTemplates;
  // A pointer to a DiagnosticsEngine for error reporting.
  clang::DiagnosticsEngine &Diags;
  Index Idx;
  int Granularity; // Granularity of ftime trace
  bool PublicOnly; // Indicates if only public declarations are documented.
  bool FTimeTrace; // Indicates if ftime trace is turned on
};

} // namespace doc
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
