//===--- IncludeOrderCheck.cpp - clang-tidy -------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "IncludeOrderCheck.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"

#include <map>

namespace clang {
namespace tidy {
namespace llvm {

namespace {
class IncludeOrderPPCallbacks : public PPCallbacks {
public:
  explicit IncludeOrderPPCallbacks(ClangTidyCheck &Check, SourceManager &SM)
      : LookForMainModule(true), Check(Check), SM(SM) {}

  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                          StringRef FileName, bool IsAngled,
                          CharSourceRange FilenameRange, const FileEntry *File,
                          StringRef SearchPath, StringRef RelativePath,
                          const Module *Imported,
                          SrcMgr::CharacteristicKind FileType) override;
  void EndOfMainFile() override;

private:
  struct IncludeDirective {
    SourceLocation Loc;    ///< '#' location in the include directive
    CharSourceRange Range; ///< SourceRange for the file name
    std::string Filename;  ///< Filename as a string
    bool IsAngled;         ///< true if this was an include with angle brackets
    bool IsMainModule;     ///< true if this was the first include in a file
  };

  typedef std::vector<IncludeDirective> FileIncludes;
  std::map<clang::FileID, FileIncludes> IncludeDirectives;
  bool LookForMainModule;

  ClangTidyCheck &Check;
  SourceManager &SM;
};
} // namespace

void IncludeOrderCheck::registerPPCallbacks(CompilerInstance &Compiler) {
  Compiler.getPreprocessor().addPPCallbacks(
      ::llvm::make_unique<IncludeOrderPPCallbacks>(
          *this, Compiler.getSourceManager()));
}

static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) {
  // We leave the main module header at the top.
  if (IsMainModule)
    return 0;

  // LLVM and clang headers are in the penultimate position.
  if (Filename.startswith("llvm/") || Filename.startswith("llvm-c/") ||
      Filename.startswith("clang/") || Filename.startswith("clang-c/"))
    return 2;

  // System headers are sorted to the end.
  if (IsAngled || Filename.startswith("gtest/"))
    return 3;

  // Other headers are inserted between the main module header and LLVM headers.
  return 1;
}

void IncludeOrderPPCallbacks::InclusionDirective(
    SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
    bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
    StringRef SearchPath, StringRef RelativePath, const Module *Imported,
    SrcMgr::CharacteristicKind FileType) {
  // We recognize the first include as a special main module header and want
  // to leave it in the top position.
  IncludeDirective ID = {HashLoc, FilenameRange, FileName, IsAngled, false};
  if (LookForMainModule && !IsAngled) {
    ID.IsMainModule = true;
    LookForMainModule = false;
  }

  // Bucket the include directives by the id of the file they were declared in.
  IncludeDirectives[SM.getFileID(HashLoc)].push_back(std::move(ID));
}

void IncludeOrderPPCallbacks::EndOfMainFile() {
  LookForMainModule = true;
  if (IncludeDirectives.empty())
    return;

  // TODO: find duplicated includes.

  // Form blocks of includes. We don't want to sort across blocks. This also
  // implicitly makes us never reorder over #defines or #if directives.
  // FIXME: We should be more careful about sorting below comments as we don't
  // know if the comment refers to the next include or the whole block that
  // follows.
  for (auto &Bucket : IncludeDirectives) {
    auto &FileDirectives = Bucket.second;
    std::vector<unsigned> Blocks(1, 0);
    for (unsigned I = 1, E = FileDirectives.size(); I != E; ++I)
      if (SM.getExpansionLineNumber(FileDirectives[I].Loc) !=
          SM.getExpansionLineNumber(FileDirectives[I - 1].Loc) + 1)
        Blocks.push_back(I);
    Blocks.push_back(FileDirectives.size()); // Sentinel value.

    // Get a vector of indices.
    std::vector<unsigned> IncludeIndices;
    for (unsigned I = 0, E = FileDirectives.size(); I != E; ++I)
      IncludeIndices.push_back(I);

    // Sort the includes. We first sort by priority, then lexicographically.
    for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI)
      std::sort(IncludeIndices.begin() + Blocks[BI],
                IncludeIndices.begin() + Blocks[BI + 1],
                [&FileDirectives](unsigned LHSI, unsigned RHSI) {
                  IncludeDirective &LHS = FileDirectives[LHSI];
                  IncludeDirective &RHS = FileDirectives[RHSI];

                  int PriorityLHS =
                      getPriority(LHS.Filename, LHS.IsAngled, LHS.IsMainModule);
                  int PriorityRHS =
                      getPriority(RHS.Filename, RHS.IsAngled, RHS.IsMainModule);

                  return std::tie(PriorityLHS, LHS.Filename) <
                         std::tie(PriorityRHS, RHS.Filename);
                });

    // Emit a warning for each block and fixits for all changes within that
    // block.
    for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI) {
      // Find the first include that's not in the right position.
      unsigned I, E;
      for (I = Blocks[BI], E = Blocks[BI + 1]; I != E; ++I)
        if (IncludeIndices[I] != I)
          break;

      if (I == E)
        continue;

      // Emit a warning.
      auto D = Check.diag(FileDirectives[I].Loc,
                          "#includes are not sorted properly");

      // Emit fix-its for all following includes in this block.
      for (; I != E; ++I) {
        if (IncludeIndices[I] == I)
          continue;
        const IncludeDirective &CopyFrom = FileDirectives[IncludeIndices[I]];

        SourceLocation FromLoc = CopyFrom.Range.getBegin();
        const char *FromData = SM.getCharacterData(FromLoc);
        unsigned FromLen = std::strcspn(FromData, "\n");

        StringRef FixedName(FromData, FromLen);

        SourceLocation ToLoc = FileDirectives[I].Range.getBegin();
        const char *ToData = SM.getCharacterData(ToLoc);
        unsigned ToLen = std::strcspn(ToData, "\n");
        auto ToRange =
            CharSourceRange::getCharRange(ToLoc, ToLoc.getLocWithOffset(ToLen));

        D << FixItHint::CreateReplacement(ToRange, FixedName);
      }
    }
  }

  IncludeDirectives.clear();
}

} // namespace llvm
} // namespace tidy
} // namespace clang
