//===-------- IncludeInserter.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 "IncludeInserter.h"
#include "clang/Lex/Token.h"

namespace clang {
namespace tidy {
namespace utils {

class IncludeInserterCallback : public PPCallbacks {
public:
  explicit IncludeInserterCallback(IncludeInserter *Inserter)
      : Inserter(Inserter) {}
  // Implements PPCallbacks::InclusionDerective(). Records the names and source
  // locations of the inclusions in the main source file being processed.
  void InclusionDirective(SourceLocation HashLocation,
                          const Token &IncludeToken, StringRef FileNameRef,
                          bool IsAngled, CharSourceRange FileNameRange,
                          const FileEntry * /*IncludedFile*/,
                          StringRef /*SearchPath*/, StringRef /*RelativePath*/,
                          const Module * /*ImportedModule*/,
                          SrcMgr::CharacteristicKind /*FileType*/) override {
    Inserter->AddInclude(FileNameRef, IsAngled, HashLocation,
                         IncludeToken.getEndLoc());
  }

private:
  IncludeInserter *Inserter;
};

IncludeInserter::IncludeInserter(const SourceManager &SourceMgr,
                                 const LangOptions &LangOpts,
                                 IncludeSorter::IncludeStyle Style)
    : SourceMgr(SourceMgr), LangOpts(LangOpts), Style(Style) {}

IncludeInserter::~IncludeInserter() {}

std::unique_ptr<PPCallbacks> IncludeInserter::CreatePPCallbacks() {
  return llvm::make_unique<IncludeInserterCallback>(this);
}

llvm::Optional<FixItHint>
IncludeInserter::CreateIncludeInsertion(FileID FileID, StringRef Header,
                                        bool IsAngled) {
  // We assume the same Header will never be included both angled and not
  // angled.
  if (!InsertedHeaders[FileID].insert(Header).second)
    return llvm::None;

  if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) {
    // This may happen if there have been no preprocessor directives in this
    // file.
    IncludeSorterByFile.insert(std::make_pair(
        FileID,
        llvm::make_unique<IncludeSorter>(
            &SourceMgr, &LangOpts, FileID,
            SourceMgr.getFilename(SourceMgr.getLocForStartOfFile(FileID)),
            Style)));
  }
  return IncludeSorterByFile[FileID]->CreateIncludeInsertion(Header, IsAngled);
}

void IncludeInserter::AddInclude(StringRef FileName, bool IsAngled,
                                 SourceLocation HashLocation,
                                 SourceLocation EndLocation) {
  FileID FileID = SourceMgr.getFileID(HashLocation);
  if (IncludeSorterByFile.find(FileID) == IncludeSorterByFile.end()) {
    IncludeSorterByFile.insert(std::make_pair(
        FileID, llvm::make_unique<IncludeSorter>(
                    &SourceMgr, &LangOpts, FileID,
                    SourceMgr.getFilename(HashLocation), Style)));
  }
  IncludeSorterByFile[FileID]->AddInclude(FileName, IsAngled, HashLocation,
                                          EndLocation);
}

} // namespace utils
} // namespace tidy
} // namespace clang
