//===--- FillInMissingSwitchEnumCases.cpp -  ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Edit/RefactoringFixits.h"
#include <unordered_map>

using namespace clang;

namespace {

struct CaseInfo {
  const SwitchCase *Case, *NextCase;
  unsigned Index;
};
typedef std::unordered_map<int64_t, CaseInfo> CoveredEnumCasesInfoType;

/// Return true if the ordering of the covered enum cases is similar to the
/// order of the enum case constants that are defined in the enum.
bool useCaseBasedOrdering(const ArrayRef<int64_t> &CoveredEnumCaseValues,
                          const CoveredEnumCasesInfoType &CoveredEnumCases) {
  if (CoveredEnumCaseValues.empty())
    return false;
  for (const auto &I : llvm::enumerate(CoveredEnumCaseValues)) {
    auto It = CoveredEnumCases.find(I.value());
    if (It == CoveredEnumCases.end())
      return false;
    const CaseInfo &Case = It->second;
    if (Case.Index != I.index())
      return false;
  }
  return true;
}

/// Determine if the inserted cases should be wrapped in braces using a simple
/// heuristic:
///   Wrap only if at least 90% of existing cases use braces.
bool useBraces(const SwitchStmt *S) {
  unsigned CaseCount = 0, CompoundCasesCount = 0;
  for (const SwitchCase *Case = S->getSwitchCaseList(); Case;
       Case = Case->getNextSwitchCase(), ++CaseCount) {
    if (!Case->getSubStmt())
      continue;
    if (isa<CompoundStmt>(Case->getSubStmt()))
      ++CompoundCasesCount;
  }
  return CaseCount && float(CompoundCasesCount) / float(CaseCount) >= 0.9;
}

} // end anonymous namespace

void edit::fillInMissingSwitchEnumCases(
    ASTContext &Context, const SwitchStmt *Switch, const EnumDecl *Enum,
    const DeclContext *SwitchContext,
    llvm::function_ref<void(const FixItHint &)> Consumer) {
  // Compute the number of cases in the switch.
  unsigned CaseCount = 0;
  for (const SwitchCase *Case = Switch->getSwitchCaseList(); Case;
       Case = Case->getNextSwitchCase())
    ++CaseCount;

  // Compute the set of enum values that are covered by the switch.
  CoveredEnumCasesInfoType CoveredEnumCases;
  const SwitchCase *DefaultCase = nullptr;
  const SwitchCase *FirstCoveredEnumCase = nullptr;
  const SwitchCase *NextCase = nullptr;
  unsigned CaseIndex = CaseCount;
  for (const SwitchCase *Case = Switch->getSwitchCaseList(); Case;
       NextCase = Case, Case = Case->getNextSwitchCase()) {
    // The cases in the switch are ordered back to front, so the index has
    // to be reversed.
    --CaseIndex;
    if (isa<DefaultStmt>(Case)) {
      DefaultCase = Case;
      continue;
    }
    const auto *CS = cast<CaseStmt>(Case);
    if (const auto *LHS = CS->getLHS()) {
      llvm::APSInt Value;
      if (!LHS->EvaluateAsInt(Value, Context))
        continue;
      // Only allow constant that fix into 64 bits.
      if (Value.getMinSignedBits() > 64)
        continue;
      CoveredEnumCases[Value.getSExtValue()] =
          CaseInfo{Case, NextCase, CaseIndex};
      // The cases in the switch are ordered back to front, so the last
      //  case is actually the first enum case in the switch.
      FirstCoveredEnumCase = Case;
    }
  }

  // Wrap the inserted cases in braces using a simple heuristic:
  //   Wrap only if at least 90% of existing cases use braces.
  bool WrapInBraces = useBraces(Switch);
  auto CreateReplacementForMissingCaseGroup =
      [&](ArrayRef<const EnumConstantDecl *> UncoveredEnumCases,
          SourceLocation InsertionLoc = SourceLocation()) {
        if (UncoveredEnumCases.empty())
          return;
        std::string Result;
        llvm::raw_string_ostream OS(Result);
        for (const auto *EnumCase : UncoveredEnumCases) {
          OS << "case ";
          if (SwitchContext) {
            const auto *NS = NestedNameSpecifier::getRequiredQualification(
                Context, SwitchContext, Enum->getLexicalDeclContext());
            if (NS)
              NS->print(OS, Context.getPrintingPolicy());
          }
          if (Enum->isScoped())
            OS << Enum->getName() << "::";
          OS << EnumCase->getName() << ":";
          if (WrapInBraces)
            OS << " {";
          OS << "\n<#code#>\nbreak;\n";
          if (WrapInBraces)
            OS << "}\n";
        }

        if (InsertionLoc.isInvalid()) {
          // Insert the cases before the 'default' if it's the last case in the
          // switch.
          // Note: Switch cases are ordered back to front, so the last default
          // case would be the first case in the switch statement.
          if (DefaultCase && DefaultCase == Switch->getSwitchCaseList())
            InsertionLoc = DefaultCase->getLocStart();
          else
            InsertionLoc = Switch->getBody()->getLocEnd();
        }
        Consumer(FixItHint::CreateInsertion(
            Context.getSourceManager().getSpellingLoc(InsertionLoc), OS.str()));
      };

  // Determine which enum cases are uncovered.

  llvm::SmallVector<std::pair<const EnumConstantDecl *, int64_t>, 8> EnumCases;
  llvm::SmallVector<int64_t, 8> CoveredEnumCaseValues;
  for (const auto *EnumCase : Enum->enumerators()) {
    if (EnumCase->getInitVal().getMinSignedBits() > 64)
      continue;
    int64_t Value = EnumCase->getInitVal().getSExtValue();
    EnumCases.push_back(std::make_pair(EnumCase, Value));
    if (CoveredEnumCases.count(Value))
      CoveredEnumCaseValues.push_back(Value);
  }

  llvm::SmallVector<const EnumConstantDecl *, 8> UncoveredEnumCases;
  // Figure out if the ordering of the covered enum cases is similar to the
  // order of enum case values defined in the enum.
  if (useCaseBasedOrdering(CoveredEnumCaseValues, CoveredEnumCases)) {
    // Start inserting before the first covered case.
    SourceLocation InsertionLoc = FirstCoveredEnumCase->getLocStart();

    for (const auto &EnumCase : EnumCases) {
      if (!CoveredEnumCases.count(EnumCase.second)) {
        UncoveredEnumCases.push_back(EnumCase.first);
        continue;
      }
      // Create the insertion source replacement for this set of uncovered
      // cases.
      CreateReplacementForMissingCaseGroup(UncoveredEnumCases, InsertionLoc);
      UncoveredEnumCases.clear();
      // Find the insertion location for the next set of uncovered cases.
      auto It = CoveredEnumCases.find(EnumCase.second);
      assert(It != CoveredEnumCases.end() && "Missing enum case");
      const CaseInfo &Case = It->second;
      InsertionLoc = Case.NextCase ? Case.NextCase->getLocStart()
                                   : /*Insert before end*/ SourceLocation();
    }
    CreateReplacementForMissingCaseGroup(UncoveredEnumCases, InsertionLoc);
  } else {
    // Gather all of the uncovered enum cases.
    for (const auto &EnumCase : EnumCases) {
      if (!CoveredEnumCases.count(EnumCase.second))
        UncoveredEnumCases.push_back(EnumCase.first);
    }
    assert(!UncoveredEnumCases.empty() &&
           "Can't fill-in enum cases in a full switch");
    CreateReplacementForMissingCaseGroup(UncoveredEnumCases);
  }
}
