//===--- TidyProvider.cpp - create options for running 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 "TidyProvider.h"
#include "../clang-tidy/ClangTidyModuleRegistry.h"
#include "../clang-tidy/ClangTidyOptions.h"
#include "Config.h"
#include "support/FileCache.h"
#include "support/Logger.h"
#include "support/Path.h"
#include "support/ThreadsafeFS.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/SourceMgr.h"
#include <memory>
#include <optional>

namespace clang {
namespace clangd {
namespace {

// Access to config from a .clang-tidy file, caching IO and parsing.
class DotClangTidyCache : private FileCache {
  // We cache and expose shared_ptr to avoid copying the value on every lookup
  // when we're ultimately just going to pass it to mergeWith.
  mutable std::shared_ptr<const tidy::ClangTidyOptions> Value;

public:
  DotClangTidyCache(PathRef Path) : FileCache(Path) {}

  std::shared_ptr<const tidy::ClangTidyOptions>
  get(const ThreadsafeFS &TFS,
      std::chrono::steady_clock::time_point FreshTime) const {
    std::shared_ptr<const tidy::ClangTidyOptions> Result;
    read(
        TFS, FreshTime,
        [this](std::optional<llvm::StringRef> Data) {
          Value.reset();
          if (Data && !Data->empty()) {
            auto Diagnostics = [](const llvm::SMDiagnostic &D) {
              switch (D.getKind()) {
              case llvm::SourceMgr::DK_Error:
                elog("tidy-config error at {0}:{1}:{2}: {3}", D.getFilename(),
                     D.getLineNo(), D.getColumnNo(), D.getMessage());
                break;
              case llvm::SourceMgr::DK_Warning:
                log("tidy-config warning at {0}:{1}:{2}: {3}", D.getFilename(),
                    D.getLineNo(), D.getColumnNo(), D.getMessage());
                break;
              case llvm::SourceMgr::DK_Note:
              case llvm::SourceMgr::DK_Remark:
                vlog("tidy-config note at {0}:{1}:{2}: {3}", D.getFilename(),
                     D.getLineNo(), D.getColumnNo(), D.getMessage());
                break;
              }
            };
            if (auto Parsed = tidy::parseConfigurationWithDiags(
                    llvm::MemoryBufferRef(*Data, path()), Diagnostics))
              Value = std::make_shared<const tidy::ClangTidyOptions>(
                  std::move(*Parsed));
            else
              elog("Error parsing clang-tidy configuration in {0}: {1}", path(),
                   Parsed.getError().message());
          }
        },
        [&]() { Result = Value; });
    return Result;
  }
};

// Access to combined config from .clang-tidy files governing a source file.
// Each config file is cached and the caches are shared for affected sources.
//
// FIXME: largely duplicates config::Provider::fromAncestorRelativeYAMLFiles.
// Potentially useful for compile_commands.json too. Extract?
class DotClangTidyTree {
  const ThreadsafeFS &FS;
  std::string RelPath;
  std::chrono::steady_clock::duration MaxStaleness;

  mutable std::mutex Mu;
  // Keys are the ancestor directory, not the actual config path within it.
  // We only insert into this map, so pointers to values are stable forever.
  // Mutex guards the map itself, not the values (which are threadsafe).
  mutable llvm::StringMap<DotClangTidyCache> Cache;

public:
  DotClangTidyTree(const ThreadsafeFS &FS)
      : FS(FS), RelPath(".clang-tidy"), MaxStaleness(std::chrono::seconds(5)) {}

  void apply(tidy::ClangTidyOptions &Result, PathRef AbsPath) {
    namespace path = llvm::sys::path;
    assert(path::is_absolute(AbsPath));

    // Compute absolute paths to all ancestors (substrings of P.Path).
    // Ensure cache entries for each ancestor exist in the map.
    llvm::SmallVector<DotClangTidyCache *> Caches;
    {
      std::lock_guard<std::mutex> Lock(Mu);
      for (auto Ancestor = absoluteParent(AbsPath); !Ancestor.empty();
           Ancestor = absoluteParent(Ancestor)) {
        auto It = Cache.find(Ancestor);
        // Assemble the actual config file path only if needed.
        if (It == Cache.end()) {
          llvm::SmallString<256> ConfigPath = Ancestor;
          path::append(ConfigPath, RelPath);
          It = Cache.try_emplace(Ancestor, ConfigPath.str()).first;
        }
        Caches.push_back(&It->second);
      }
    }
    // Finally query each individual file.
    // This will take a (per-file) lock for each file that actually exists.
    std::chrono::steady_clock::time_point FreshTime =
        std::chrono::steady_clock::now() - MaxStaleness;
    llvm::SmallVector<std::shared_ptr<const tidy::ClangTidyOptions>>
        OptionStack;
    for (const DotClangTidyCache *Cache : Caches)
      if (auto Config = Cache->get(FS, FreshTime)) {
        OptionStack.push_back(std::move(Config));
        if (!OptionStack.back()->InheritParentConfig.value_or(false))
          break;
      }
    unsigned Order = 1u;
    for (auto &Option : llvm::reverse(OptionStack))
      Result.mergeWith(*Option, Order++);
  }
};

} // namespace

static void mergeCheckList(std::optional<std::string> &Checks,
                           llvm::StringRef List) {
  if (List.empty())
    return;
  if (!Checks || Checks->empty()) {
    Checks.emplace(List);
    return;
  }
  *Checks = llvm::join_items(",", *Checks, List);
}

TidyProvider provideEnvironment() {
  static const std::optional<std::string> User = [] {
    std::optional<std::string> Ret = llvm::sys::Process::GetEnv("USER");
#ifdef _WIN32
    if (!Ret)
      return llvm::sys::Process::GetEnv("USERNAME");
#endif
    return Ret;
  }();

  if (User)
    return
        [](tidy::ClangTidyOptions &Opts, llvm::StringRef) { Opts.User = User; };
  // FIXME: Once function_ref and unique_function operator= operators handle
  // null values, this can return null.
  return [](tidy::ClangTidyOptions &, llvm::StringRef) {};
}

TidyProvider provideDefaultChecks() {
  // These default checks are chosen for:
  //  - low false-positive rate
  //  - providing a lot of value
  //  - being reasonably efficient
  static const std::string DefaultChecks = llvm::join_items(
      ",", "readability-misleading-indentation", "readability-deleted-default",
      "bugprone-integer-division", "bugprone-sizeof-expression",
      "bugprone-suspicious-missing-comma", "bugprone-unused-raii",
      "bugprone-unused-return-value", "misc-unused-using-decls",
      "misc-unused-alias-decls", "misc-definitions-in-headers");
  return [](tidy::ClangTidyOptions &Opts, llvm::StringRef) {
    if (!Opts.Checks || Opts.Checks->empty())
      Opts.Checks = DefaultChecks;
  };
}

TidyProvider addTidyChecks(llvm::StringRef Checks,
                           llvm::StringRef WarningsAsErrors) {
  return [Checks = std::string(Checks),
          WarningsAsErrors = std::string(WarningsAsErrors)](
             tidy::ClangTidyOptions &Opts, llvm::StringRef) {
    mergeCheckList(Opts.Checks, Checks);
    mergeCheckList(Opts.WarningsAsErrors, WarningsAsErrors);
  };
}

TidyProvider disableUnusableChecks(llvm::ArrayRef<std::string> ExtraBadChecks) {
  constexpr llvm::StringLiteral Separator(",");
  static const std::string BadChecks = llvm::join_items(
      Separator,
      // We want this list to start with a separator to
      // simplify appending in the lambda. So including an
      // empty string here will force that.
      "",
      // include-cleaner is directly integrated in IncludeCleaner.cpp
      "-misc-include-cleaner",

      // ----- False Positives -----

      // Check relies on seeing ifndef/define/endif directives,
      // clangd doesn't replay those when using a preamble.
      "-llvm-header-guard", "-modernize-macro-to-enum",
      "-cppcoreguidelines-macro-to-enum",

      // ----- Crashing Checks -----

      // Check can choke on invalid (intermediate) c++
      // code, which is often the case when clangd
      // tries to build an AST.
      "-bugprone-use-after-move",
      // Alias for bugprone-use-after-move.
      "-hicpp-invalid-access-moved",
      // Check uses dataflow analysis, which might hang/crash unexpectedly on
      // incomplete code.
      "-bugprone-unchecked-optional-access");

  size_t Size = BadChecks.size();
  for (const std::string &Str : ExtraBadChecks) {
    if (Str.empty())
      continue;
    Size += Separator.size();
    if (LLVM_LIKELY(Str.front() != '-'))
      ++Size;
    Size += Str.size();
  }
  std::string DisableGlob;
  DisableGlob.reserve(Size);
  DisableGlob += BadChecks;
  for (const std::string &Str : ExtraBadChecks) {
    if (Str.empty())
      continue;
    DisableGlob += Separator;
    if (LLVM_LIKELY(Str.front() != '-'))
      DisableGlob.push_back('-');
    DisableGlob += Str;
  }

  return [DisableList(std::move(DisableGlob))](tidy::ClangTidyOptions &Opts,
                                               llvm::StringRef) {
    if (Opts.Checks && !Opts.Checks->empty())
      Opts.Checks->append(DisableList);
  };
}

TidyProvider provideClangdConfig() {
  return [](tidy::ClangTidyOptions &Opts, llvm::StringRef) {
    const auto &CurTidyConfig = Config::current().Diagnostics.ClangTidy;
    if (!CurTidyConfig.Checks.empty())
      mergeCheckList(Opts.Checks, CurTidyConfig.Checks);

    for (const auto &CheckOption : CurTidyConfig.CheckOptions)
      Opts.CheckOptions.insert_or_assign(CheckOption.getKey(),
                                         tidy::ClangTidyOptions::ClangTidyValue(
                                             CheckOption.getValue(), 10000U));
  };
}

TidyProvider provideClangTidyFiles(ThreadsafeFS &TFS) {
  return [Tree = std::make_unique<DotClangTidyTree>(TFS)](
             tidy::ClangTidyOptions &Opts, llvm::StringRef Filename) {
    Tree->apply(Opts, Filename);
  };
}

TidyProvider combine(std::vector<TidyProvider> Providers) {
  // FIXME: Once function_ref and unique_function operator= operators handle
  // null values, we should filter out any Providers that are null. Right now we
  // have to ensure we dont pass any providers that are null.
  return [Providers(std::move(Providers))](tidy::ClangTidyOptions &Opts,
                                           llvm::StringRef Filename) {
    for (const auto &Provider : Providers)
      Provider(Opts, Filename);
  };
}

tidy::ClangTidyOptions getTidyOptionsForFile(TidyProviderRef Provider,
                                             llvm::StringRef Filename) {
  // getDefaults instantiates all check factories, which are registered at link
  // time. So cache the results once.
  static const auto *DefaultOpts = [] {
    auto *Opts = new tidy::ClangTidyOptions;
    *Opts = tidy::ClangTidyOptions::getDefaults();
    Opts->Checks->clear();
    return Opts;
  }();
  auto Opts = *DefaultOpts;
  if (Provider)
    Provider(Opts, Filename);
  return Opts;
}

bool isRegisteredTidyCheck(llvm::StringRef Check) {
  assert(!Check.empty());
  assert(!Check.contains('*') && !Check.contains(',') &&
         "isRegisteredCheck doesn't support globs");
  assert(Check.ltrim().front() != '-');

  static const llvm::StringSet<llvm::BumpPtrAllocator> AllChecks = [] {
    llvm::StringSet<llvm::BumpPtrAllocator> Result;
    tidy::ClangTidyCheckFactories Factories;
    for (tidy::ClangTidyModuleRegistry::entry E :
         tidy::ClangTidyModuleRegistry::entries())
      E.instantiate()->addCheckFactories(Factories);
    for (const auto &Factory : Factories)
      Result.insert(Factory.getKey());
    return Result;
  }();

  return AllChecks.contains(Check);
}

std::optional<bool> isFastTidyCheck(llvm::StringRef Check) {
  static auto &Fast = *new llvm::StringMap<bool>{
#define FAST(CHECK, TIME) {#CHECK,true},
#define SLOW(CHECK, TIME) {#CHECK,false},
#include "TidyFastChecks.inc"
  };
  if (auto It = Fast.find(Check); It != Fast.end())
    return It->second;
  return std::nullopt;
}

} // namespace clangd
} // namespace clang
