//===--- CheckerRegistry.cpp - Maintains all available checkers -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/CheckerRegistry.h"
#include "clang/StaticAnalyzer/Core/CheckerOptInfo.h"

using namespace clang;
using namespace ento;

static const char PackageSeparator = '.';
typedef llvm::DenseSet<const CheckerRegistry::CheckerInfo *> CheckerInfoSet;


static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a,
                          const CheckerRegistry::CheckerInfo &b) {
  return a.FullName < b.FullName;
}

static bool isInPackage(const CheckerRegistry::CheckerInfo &checker,
                        StringRef packageName) {
  // Does the checker's full name have the package as a prefix?
  if (!checker.FullName.startswith(packageName))
    return false;

  // Is the package actually just the name of a specific checker?
  if (checker.FullName.size() == packageName.size())
    return true;

  // Is the checker in the package (or a subpackage)?
  if (checker.FullName[packageName.size()] == PackageSeparator)
    return true;

  return false;
}

static void collectCheckers(const CheckerRegistry::CheckerInfoList &checkers,
                            const llvm::StringMap<size_t> &packageSizes,
                            CheckerOptInfo &opt, CheckerInfoSet &collected) {
  // Use a binary search to find the possible start of the package.
  CheckerRegistry::CheckerInfo packageInfo(NULL, opt.getName(), "");
  CheckerRegistry::CheckerInfoList::const_iterator e = checkers.end();
  CheckerRegistry::CheckerInfoList::const_iterator i =
    std::lower_bound(checkers.begin(), e, packageInfo, checkerNameLT);

  // If we didn't even find a possible package, give up.
  if (i == e)
    return;

  // If what we found doesn't actually start the package, give up.
  if (!isInPackage(*i, opt.getName()))
    return;

  // There is at least one checker in the package; claim the option.
  opt.claim();

  // See how large the package is.
  // If the package doesn't exist, assume the option refers to a single checker.
  size_t size = 1;
  llvm::StringMap<size_t>::const_iterator packageSize =
    packageSizes.find(opt.getName());
  if (packageSize != packageSizes.end())
    size = packageSize->getValue();

  // Step through all the checkers in the package.
  for (e = i+size; i != e; ++i) {
    if (opt.isEnabled())
      collected.insert(&*i);
    else
      collected.erase(&*i);
  }
}

void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name,
                                 StringRef desc) {
  Checkers.push_back(CheckerInfo(fn, name, desc));

  // Record the presence of the checker in its packages.
  StringRef packageName, leafName;
  llvm::tie(packageName, leafName) = name.rsplit(PackageSeparator);
  while (!leafName.empty()) {
    Packages[packageName] += 1;
    llvm::tie(packageName, leafName) = packageName.rsplit(PackageSeparator);
  }
}

void CheckerRegistry::initializeManager(CheckerManager &checkerMgr, 
                                  SmallVectorImpl<CheckerOptInfo> &opts) const {
  // Sort checkers for efficient collection.
  std::sort(Checkers.begin(), Checkers.end(), checkerNameLT);

  // Collect checkers enabled by the options.
  CheckerInfoSet enabledCheckers;
  for (SmallVectorImpl<CheckerOptInfo>::iterator
         i = opts.begin(), e = opts.end(); i != e; ++i) {
    collectCheckers(Checkers, Packages, *i, enabledCheckers);
  }

  // Initialize the CheckerManager with all enabled checkers.
  for (CheckerInfoSet::iterator
         i = enabledCheckers.begin(), e = enabledCheckers.end(); i != e; ++i) {
    (*i)->Initialize(checkerMgr);
  }
}

void CheckerRegistry::printHelp(llvm::raw_ostream &out,
                                size_t maxNameChars) const {
  // FIXME: Alphabetical sort puts 'experimental' in the middle.
  // Would it be better to name it '~experimental' or something else
  // that's ASCIIbetically last?
  std::sort(Checkers.begin(), Checkers.end(), checkerNameLT);

  // FIXME: Print available packages.

  out << "CHECKERS:\n";

  // Find the maximum option length.
  size_t optionFieldWidth = 0;
  for (CheckerInfoList::const_iterator i = Checkers.begin(), e = Checkers.end();
       i != e; ++i) {
    // Limit the amount of padding we are willing to give up for alignment.
    //   Package.Name     Description  [Hidden]
    size_t nameLength = i->FullName.size();
    if (nameLength <= maxNameChars)
      optionFieldWidth = std::max(optionFieldWidth, nameLength);
  }

  const size_t initialPad = 2;
  for (CheckerInfoList::const_iterator i = Checkers.begin(), e = Checkers.end();
       i != e; ++i) {
    out.indent(initialPad) << i->FullName;

    int pad = optionFieldWidth - i->FullName.size();

    // Break on long option names.
    if (pad < 0) {
      out << '\n';
      pad = optionFieldWidth + initialPad;
    }
    out.indent(pad + 2) << i->Desc;

    out << '\n';
  }
}
