//===- TreeView.cpp - diagtool tool for printing warning flags ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DiagTool.h"
#include "DiagnosticNames.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/Basic/AllDiagnostics.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Process.h"

DEF_DIAGTOOL("tree", "Show warning flags in a tree view", TreeView)

using namespace clang;
using namespace diagtool;

static bool hasColors(const llvm::raw_ostream &out) {
  if (&out != &llvm::errs() && &out != &llvm::outs())
    return false;
  return llvm::errs().is_displayed() && llvm::outs().is_displayed();
}

class TreePrinter {
public:
  llvm::raw_ostream &out;
  const bool ShowColors;
  bool Internal;

  TreePrinter(llvm::raw_ostream &out)
      : out(out), ShowColors(hasColors(out)), Internal(false) {}

  void setColor(llvm::raw_ostream::Colors Color) {
    if (ShowColors)
      out << llvm::sys::Process::OutputColor(Color, false, false);
  }

  void resetColor() {
    if (ShowColors)
      out << llvm::sys::Process::ResetColor();
  }

  static bool isIgnored(unsigned DiagID) {
    // FIXME: This feels like a hack.
    static clang::DiagnosticsEngine Diags(new DiagnosticIDs,
                                          new DiagnosticOptions);
    return Diags.isIgnored(DiagID, SourceLocation());
  }

  static bool enabledByDefault(const GroupRecord &Group) {
    for (const DiagnosticRecord &DR : Group.diagnostics()) {
      if (isIgnored(DR.DiagID))
        return false;
    }

    for (const GroupRecord &GR : Group.subgroups()) {
      if (!enabledByDefault(GR))
        return false;
    }

    return true;
  }

  void printGroup(const GroupRecord &Group, unsigned Indent = 0) {
    out.indent(Indent * 2);

    if (enabledByDefault(Group))
      setColor(llvm::raw_ostream::GREEN);
    else
      setColor(llvm::raw_ostream::YELLOW);

    out << "-W" << Group.getName() << "\n";
    resetColor();

    ++Indent;
    for (const GroupRecord &GR : Group.subgroups()) {
      printGroup(GR, Indent);
    }

    if (Internal) {
      for (const DiagnosticRecord &DR : Group.diagnostics()) {
        if (ShowColors && !isIgnored(DR.DiagID))
          setColor(llvm::raw_ostream::GREEN);
        out.indent(Indent * 2);
        out << DR.getName();
        resetColor();
        out << "\n";
      }
    }
  }

  int showGroup(StringRef RootGroup) {
    ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();

    if (RootGroup.size() > UINT16_MAX) {
      llvm::errs() << "No such diagnostic group exists\n";
      return 1;
    }

    const GroupRecord *Found =
        std::lower_bound(AllGroups.begin(), AllGroups.end(), RootGroup);

    if (Found == AllGroups.end() || Found->getName() != RootGroup) {
      llvm::errs() << "No such diagnostic group exists\n";
      return 1;
    }

    printGroup(*Found);

    return 0;
  }

  int showAll() {
    ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
    llvm::DenseSet<unsigned> NonRootGroupIDs;

    for (const GroupRecord &GR : AllGroups) {
      for (auto SI = GR.subgroup_begin(), SE = GR.subgroup_end(); SI != SE;
           ++SI) {
        NonRootGroupIDs.insert((unsigned)SI.getID());
      }
    }

    assert(NonRootGroupIDs.size() < AllGroups.size());

    for (unsigned i = 0, e = AllGroups.size(); i != e; ++i) {
      if (!NonRootGroupIDs.count(i))
        printGroup(AllGroups[i]);
    }

    return 0;
  }

  void showKey() {
    if (ShowColors) {
      out << '\n';
      setColor(llvm::raw_ostream::GREEN);
      out << "GREEN";
      resetColor();
      out << " = enabled by default\n\n";
    }
  }
};

static void printUsage() {
  llvm::errs() << "Usage: diagtool tree [--internal] [<diagnostic-group>]\n";
}

int TreeView::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
  // First check our one flag (--flags-only).
  bool Internal = false;
  if (argc > 0) {
    StringRef FirstArg(*argv);
    if (FirstArg.equals("--internal")) {
      Internal = true;
      --argc;
      ++argv;
    }
  }

  bool ShowAll = false;
  StringRef RootGroup;

  switch (argc) {
  case 0:
    ShowAll = true;
    break;
  case 1:
    RootGroup = argv[0];
    if (RootGroup.startswith("-W"))
      RootGroup = RootGroup.substr(2);
    if (RootGroup == "everything")
      ShowAll = true;
    // FIXME: Handle other special warning flags, like -pedantic.
    break;
  default:
    printUsage();
    return -1;
  }

  TreePrinter TP(out);
  TP.Internal = Internal;
  TP.showKey();
  return ShowAll ? TP.showAll() : TP.showGroup(RootGroup);
}
