//===--- DuplicateIncludeCheck.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 "DuplicateIncludeCheck.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include <memory>

namespace clang::tidy::readability {

static SourceLocation advanceBeyondCurrentLine(const SourceManager &SM,
                                               SourceLocation Start,
                                               int Offset) {
  const FileID Id = SM.getFileID(Start);
  const unsigned LineNumber = SM.getSpellingLineNumber(Start);
  while (SM.getFileID(Start) == Id &&
         SM.getSpellingLineNumber(Start.getLocWithOffset(Offset)) == LineNumber)
    Start = Start.getLocWithOffset(Offset);
  return Start;
}

namespace {

using FileList = SmallVector<StringRef>;

class DuplicateIncludeCallbacks : public PPCallbacks {
public:
  DuplicateIncludeCallbacks(DuplicateIncludeCheck &Check,
                            const SourceManager &SM)
      : Check(Check), SM(SM) {
    // The main file doesn't participate in the FileChanged notification.
    Files.emplace_back();
  }

  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                   SrcMgr::CharacteristicKind FileType,
                   FileID PrevFID) override;

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

  void MacroDefined(const Token &MacroNameTok,
                    const MacroDirective *MD) override;

  void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD,
                      const MacroDirective *Undef) override;

private:
  // A list of included files is kept for each file we enter.
  SmallVector<FileList> Files;
  DuplicateIncludeCheck &Check;
  const SourceManager &SM;
};

void DuplicateIncludeCallbacks::FileChanged(SourceLocation Loc,
                                            FileChangeReason Reason,
                                            SrcMgr::CharacteristicKind FileType,
                                            FileID PrevFID) {
  if (Reason == EnterFile)
    Files.emplace_back();
  else if (Reason == ExitFile)
    Files.pop_back();
}

void DuplicateIncludeCallbacks::InclusionDirective(
    SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
    bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File,
    StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule,
    bool ModuleImported, SrcMgr::CharacteristicKind FileType) {
  // Skip includes behind macros
  if (FilenameRange.getBegin().isMacroID() ||
      FilenameRange.getEnd().isMacroID())
    return;
  if (llvm::is_contained(Files.back(), FileName)) {
    // We want to delete the entire line, so make sure that [Start,End] covers
    // everything.
    SourceLocation Start =
        advanceBeyondCurrentLine(SM, HashLoc, -1).getLocWithOffset(-1);
    SourceLocation End =
        advanceBeyondCurrentLine(SM, FilenameRange.getEnd(), 1);
    Check.diag(HashLoc, "duplicate include")
        << FixItHint::CreateRemoval(SourceRange{Start, End});
  } else
    Files.back().push_back(FileName);
}

void DuplicateIncludeCallbacks::MacroDefined(const Token &MacroNameTok,
                                             const MacroDirective *MD) {
  Files.back().clear();
}

void DuplicateIncludeCallbacks::MacroUndefined(const Token &MacroNameTok,
                                               const MacroDefinition &MD,
                                               const MacroDirective *Undef) {
  Files.back().clear();
}

} // namespace

void DuplicateIncludeCheck::registerPPCallbacks(
    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
  PP->addPPCallbacks(std::make_unique<DuplicateIncludeCallbacks>(*this, SM));
}

} // namespace clang::tidy::readability
