//===--- IncludeOrderCheck.cpp - clang-tidy -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#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
