//===--- ConcatNestedNamespacesCheck.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 "ConcatNestedNamespacesCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include <algorithm>
#include <iterator>

namespace clang {
namespace tidy {
namespace modernize {

static bool locationsInSameFile(const SourceManager &Sources,
                                SourceLocation Loc1, SourceLocation Loc2) {
  return Loc1.isFileID() && Loc2.isFileID() &&
         Sources.getFileID(Loc1) == Sources.getFileID(Loc2);
}

static bool anonymousOrInlineNamespace(const NamespaceDecl &ND) {
  return ND.isAnonymousNamespace() || ND.isInlineNamespace();
}

static bool singleNamedNamespaceChild(const NamespaceDecl &ND) {
  NamespaceDecl::decl_range Decls = ND.decls();
  if (std::distance(Decls.begin(), Decls.end()) != 1)
    return false;

  const auto *ChildNamespace = dyn_cast<const NamespaceDecl>(*Decls.begin());
  return ChildNamespace && !anonymousOrInlineNamespace(*ChildNamespace);
}

static bool alreadyConcatenated(std::size_t NumCandidates,
                                const SourceRange &ReplacementRange,
                                const SourceManager &Sources,
                                const LangOptions &LangOpts) {
  CharSourceRange TextRange =
      Lexer::getAsCharRange(ReplacementRange, Sources, LangOpts);
  StringRef CurrentNamespacesText =
      Lexer::getSourceText(TextRange, Sources, LangOpts);
  return CurrentNamespacesText.count(':') == (NumCandidates - 1) * 2;
}

ConcatNestedNamespacesCheck::NamespaceString
ConcatNestedNamespacesCheck::concatNamespaces() {
  NamespaceString Result("namespace ");
  Result.append(Namespaces.front()->getName());

  std::for_each(std::next(Namespaces.begin()), Namespaces.end(),
                [&Result](const NamespaceDecl *ND) {
                  Result.append("::");
                  Result.append(ND->getName());
                });

  return Result;
}

void ConcatNestedNamespacesCheck::registerMatchers(
    ast_matchers::MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus17)
    return;

  Finder->addMatcher(ast_matchers::namespaceDecl().bind("namespace"), this);
}

void ConcatNestedNamespacesCheck::reportDiagnostic(
    const SourceRange &FrontReplacement, const SourceRange &BackReplacement) {
  diag(Namespaces.front()->getBeginLoc(),
       "nested namespaces can be concatenated", DiagnosticIDs::Warning)
      << FixItHint::CreateReplacement(FrontReplacement, concatNamespaces())
      << FixItHint::CreateReplacement(BackReplacement, "}");
}

void ConcatNestedNamespacesCheck::check(
    const ast_matchers::MatchFinder::MatchResult &Result) {
  const NamespaceDecl &ND = *Result.Nodes.getNodeAs<NamespaceDecl>("namespace");
  const SourceManager &Sources = *Result.SourceManager;

  if (!locationsInSameFile(Sources, ND.getBeginLoc(), ND.getRBraceLoc()))
    return;

  if (!Sources.isInMainFile(ND.getBeginLoc()))
    return;

  if (anonymousOrInlineNamespace(ND))
    return;

  Namespaces.push_back(&ND);

  if (singleNamedNamespaceChild(ND))
    return;

  SourceRange FrontReplacement(Namespaces.front()->getBeginLoc(),
                               Namespaces.back()->getLocation());
  SourceRange BackReplacement(Namespaces.back()->getRBraceLoc(),
                              Namespaces.front()->getRBraceLoc());

  if (!alreadyConcatenated(Namespaces.size(), FrontReplacement, Sources,
                           getLangOpts()))
    reportDiagnostic(FrontReplacement, BackReplacement);

  Namespaces.clear();
}

} // namespace modernize
} // namespace tidy
} // namespace clang
