//===- CoverageReport.cpp - Code coverage report -------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This class implements rendering of a code coverage report.
//
//===----------------------------------------------------------------------===//

#include "CoverageReport.h"
#include "RenderingSupport.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/Threading.h"
#include <numeric>

using namespace llvm;

namespace {

/// Helper struct which prints trimmed and aligned columns.
struct Column {
  enum TrimKind { NoTrim, WidthTrim, RightTrim };

  enum AlignmentKind { LeftAlignment, RightAlignment };

  StringRef Str;
  unsigned Width;
  TrimKind Trim;
  AlignmentKind Alignment;

  Column(StringRef Str, unsigned Width)
      : Str(Str), Width(Width), Trim(WidthTrim), Alignment(LeftAlignment) {}

  Column &set(TrimKind Value) {
    Trim = Value;
    return *this;
  }

  Column &set(AlignmentKind Value) {
    Alignment = Value;
    return *this;
  }

  void render(raw_ostream &OS) const {
    if (Str.size() <= Width) {
      if (Alignment == RightAlignment) {
        OS.indent(Width - Str.size());
        OS << Str;
        return;
      }
      OS << Str;
      OS.indent(Width - Str.size());
      return;
    }

    switch (Trim) {
    case NoTrim:
      OS << Str;
      break;
    case WidthTrim:
      OS << Str.substr(0, Width);
      break;
    case RightTrim:
      OS << Str.substr(0, Width - 3) << "...";
      break;
    }
  }
};

raw_ostream &operator<<(raw_ostream &OS, const Column &Value) {
  Value.render(OS);
  return OS;
}

Column column(StringRef Str, unsigned Width) { return Column(Str, Width); }

template <typename T>
Column column(StringRef Str, unsigned Width, const T &Value) {
  return Column(Str, Width).set(Value);
}

// Specify the default column widths.
size_t FileReportColumns[] = {25, 12, 18, 10, 12, 18, 10, 16,
                              16, 10, 12, 18, 10, 12, 18, 10};
size_t FunctionReportColumns[] = {25, 10, 8, 8, 10, 8, 8, 10, 8, 8};

/// Adjust column widths to fit long file paths and function names.
void adjustColumnWidths(ArrayRef<StringRef> Files,
                        ArrayRef<StringRef> Functions) {
  for (StringRef Filename : Files)
    FileReportColumns[0] = std::max(FileReportColumns[0], Filename.size());
  for (StringRef Funcname : Functions)
    FunctionReportColumns[0] =
        std::max(FunctionReportColumns[0], Funcname.size());
}

/// Prints a horizontal divider long enough to cover the given column
/// widths.
void renderDivider(ArrayRef<size_t> ColumnWidths, raw_ostream &OS) {
  size_t Length = std::accumulate(ColumnWidths.begin(), ColumnWidths.end(), 0);
  for (size_t I = 0; I < Length; ++I)
    OS << '-';
}

/// Return the color which correponds to the coverage percentage of a
/// certain metric.
template <typename T>
raw_ostream::Colors determineCoveragePercentageColor(const T &Info) {
  if (Info.isFullyCovered())
    return raw_ostream::GREEN;
  return Info.getPercentCovered() >= 80.0 ? raw_ostream::YELLOW
                                          : raw_ostream::RED;
}

/// Get the number of redundant path components in each path in \p Paths.
unsigned getNumRedundantPathComponents(ArrayRef<std::string> Paths) {
  // To start, set the number of redundant path components to the maximum
  // possible value.
  SmallVector<StringRef, 8> FirstPathComponents{sys::path::begin(Paths[0]),
                                                sys::path::end(Paths[0])};
  unsigned NumRedundant = FirstPathComponents.size();

  for (unsigned I = 1, E = Paths.size(); NumRedundant > 0 && I < E; ++I) {
    StringRef Path = Paths[I];
    for (const auto &Component :
         enumerate(make_range(sys::path::begin(Path), sys::path::end(Path)))) {
      // Do not increase the number of redundant components: that would remove
      // useful parts of already-visited paths.
      if (Component.index() >= NumRedundant)
        break;

      // Lower the number of redundant components when there's a mismatch
      // between the first path, and the path under consideration.
      if (FirstPathComponents[Component.index()] != Component.value()) {
        NumRedundant = Component.index();
        break;
      }
    }
  }

  return NumRedundant;
}

/// Determine the length of the longest redundant prefix of the paths in
/// \p Paths.
unsigned getRedundantPrefixLen(ArrayRef<std::string> Paths) {
  // If there's at most one path, no path components are redundant.
  if (Paths.size() <= 1)
    return 0;

  unsigned PrefixLen = 0;
  unsigned NumRedundant = getNumRedundantPathComponents(Paths);
  auto Component = sys::path::begin(Paths[0]);
  for (unsigned I = 0; I < NumRedundant; ++I) {
    auto LastComponent = Component;
    ++Component;
    PrefixLen += Component - LastComponent;
  }
  return PrefixLen;
}

} // end anonymous namespace

namespace llvm {

void CoverageReport::render(const FileCoverageSummary &File,
                            raw_ostream &OS) const {
  auto FileCoverageColor =
      determineCoveragePercentageColor(File.RegionCoverage);
  auto FuncCoverageColor =
      determineCoveragePercentageColor(File.FunctionCoverage);
  auto InstantiationCoverageColor =
      determineCoveragePercentageColor(File.InstantiationCoverage);
  auto LineCoverageColor = determineCoveragePercentageColor(File.LineCoverage);
  SmallString<256> FileName = File.Name;
  sys::path::remove_dots(FileName, /*remove_dot_dots=*/true);
  sys::path::native(FileName);
  OS << column(FileName, FileReportColumns[0], Column::NoTrim);

  if (Options.ShowRegionSummary) {
    OS << format("%*u", FileReportColumns[1],
                 (unsigned)File.RegionCoverage.getNumRegions());
    Options.colored_ostream(OS, FileCoverageColor)
        << format("%*u", FileReportColumns[2],
                  (unsigned)(File.RegionCoverage.getNumRegions() -
                             File.RegionCoverage.getCovered()));
    if (File.RegionCoverage.getNumRegions())
      Options.colored_ostream(OS, FileCoverageColor)
          << format("%*.2f", FileReportColumns[3] - 1,
                    File.RegionCoverage.getPercentCovered())
          << '%';
    else
      OS << column("-", FileReportColumns[3], Column::RightAlignment);
  }

  OS << format("%*u", FileReportColumns[4],
               (unsigned)File.FunctionCoverage.getNumFunctions());
  OS << format("%*u", FileReportColumns[5],
               (unsigned)(File.FunctionCoverage.getNumFunctions() -
                          File.FunctionCoverage.getExecuted()));
  if (File.FunctionCoverage.getNumFunctions())
    Options.colored_ostream(OS, FuncCoverageColor)
        << format("%*.2f", FileReportColumns[6] - 1,
                  File.FunctionCoverage.getPercentCovered())
        << '%';
  else
    OS << column("-", FileReportColumns[6], Column::RightAlignment);

  if (Options.ShowInstantiationSummary) {
    OS << format("%*u", FileReportColumns[7],
                 (unsigned)File.InstantiationCoverage.getNumFunctions());
    OS << format("%*u", FileReportColumns[8],
                 (unsigned)(File.InstantiationCoverage.getNumFunctions() -
                            File.InstantiationCoverage.getExecuted()));
    if (File.InstantiationCoverage.getNumFunctions())
      Options.colored_ostream(OS, InstantiationCoverageColor)
          << format("%*.2f", FileReportColumns[9] - 1,
                    File.InstantiationCoverage.getPercentCovered())
          << '%';
    else
      OS << column("-", FileReportColumns[9], Column::RightAlignment);
  }

  OS << format("%*u", FileReportColumns[10],
               (unsigned)File.LineCoverage.getNumLines());
  Options.colored_ostream(OS, LineCoverageColor) << format(
      "%*u", FileReportColumns[11], (unsigned)(File.LineCoverage.getNumLines() -
                                               File.LineCoverage.getCovered()));
  if (File.LineCoverage.getNumLines())
    Options.colored_ostream(OS, LineCoverageColor)
        << format("%*.2f", FileReportColumns[12] - 1,
                  File.LineCoverage.getPercentCovered())
        << '%';
  else
    OS << column("-", FileReportColumns[12], Column::RightAlignment);

  if (Options.ShowBranchSummary) {
    OS << format("%*u", FileReportColumns[13],
                 (unsigned)File.BranchCoverage.getNumBranches());
    Options.colored_ostream(OS, LineCoverageColor)
        << format("%*u", FileReportColumns[14],
                  (unsigned)(File.BranchCoverage.getNumBranches() -
                             File.BranchCoverage.getCovered()));
    if (File.BranchCoverage.getNumBranches())
      Options.colored_ostream(OS, LineCoverageColor)
          << format("%*.2f", FileReportColumns[15] - 1,
                    File.BranchCoverage.getPercentCovered())
          << '%';
    else
      OS << column("-", FileReportColumns[15], Column::RightAlignment);
  }

  OS << "\n";
}

void CoverageReport::render(const FunctionCoverageSummary &Function,
                            const DemangleCache &DC,
                            raw_ostream &OS) const {
  auto FuncCoverageColor =
      determineCoveragePercentageColor(Function.RegionCoverage);
  auto LineCoverageColor =
      determineCoveragePercentageColor(Function.LineCoverage);
  OS << column(DC.demangle(Function.Name), FunctionReportColumns[0],
               Column::RightTrim)
     << format("%*u", FunctionReportColumns[1],
               (unsigned)Function.RegionCoverage.getNumRegions());
  Options.colored_ostream(OS, FuncCoverageColor)
      << format("%*u", FunctionReportColumns[2],
                (unsigned)(Function.RegionCoverage.getNumRegions() -
                           Function.RegionCoverage.getCovered()));
  Options.colored_ostream(
      OS, determineCoveragePercentageColor(Function.RegionCoverage))
      << format("%*.2f", FunctionReportColumns[3] - 1,
                Function.RegionCoverage.getPercentCovered())
      << '%';
  OS << format("%*u", FunctionReportColumns[4],
               (unsigned)Function.LineCoverage.getNumLines());
  Options.colored_ostream(OS, LineCoverageColor)
      << format("%*u", FunctionReportColumns[5],
                (unsigned)(Function.LineCoverage.getNumLines() -
                           Function.LineCoverage.getCovered()));
  Options.colored_ostream(
      OS, determineCoveragePercentageColor(Function.LineCoverage))
      << format("%*.2f", FunctionReportColumns[6] - 1,
                Function.LineCoverage.getPercentCovered())
      << '%';
  if (Options.ShowBranchSummary) {
    OS << format("%*u", FunctionReportColumns[7],
                 (unsigned)Function.BranchCoverage.getNumBranches());
    Options.colored_ostream(OS, LineCoverageColor)
        << format("%*u", FunctionReportColumns[8],
                  (unsigned)(Function.BranchCoverage.getNumBranches() -
                             Function.BranchCoverage.getCovered()));
    Options.colored_ostream(
        OS, determineCoveragePercentageColor(Function.BranchCoverage))
        << format("%*.2f", FunctionReportColumns[9] - 1,
                  Function.BranchCoverage.getPercentCovered())
        << '%';
  }
  OS << "\n";
}

void CoverageReport::renderFunctionReports(ArrayRef<std::string> Files,
                                           const DemangleCache &DC,
                                           raw_ostream &OS) {
  bool isFirst = true;
  for (StringRef Filename : Files) {
    auto Functions = Coverage.getCoveredFunctions(Filename);

    if (isFirst)
      isFirst = false;
    else
      OS << "\n";

    std::vector<StringRef> Funcnames;
    for (const auto &F : Functions)
      Funcnames.emplace_back(DC.demangle(F.Name));
    adjustColumnWidths({}, Funcnames);

    OS << "File '" << Filename << "':\n";
    OS << column("Name", FunctionReportColumns[0])
       << column("Regions", FunctionReportColumns[1], Column::RightAlignment)
       << column("Miss", FunctionReportColumns[2], Column::RightAlignment)
       << column("Cover", FunctionReportColumns[3], Column::RightAlignment)
       << column("Lines", FunctionReportColumns[4], Column::RightAlignment)
       << column("Miss", FunctionReportColumns[5], Column::RightAlignment)
       << column("Cover", FunctionReportColumns[6], Column::RightAlignment);
    if (Options.ShowBranchSummary)
      OS << column("Branches", FunctionReportColumns[7], Column::RightAlignment)
         << column("Miss", FunctionReportColumns[8], Column::RightAlignment)
         << column("Cover", FunctionReportColumns[9], Column::RightAlignment);
    OS << "\n";
    renderDivider(FunctionReportColumns, OS);
    OS << "\n";
    FunctionCoverageSummary Totals("TOTAL");
    for (const auto &F : Functions) {
      auto Function = FunctionCoverageSummary::get(Coverage, F);
      ++Totals.ExecutionCount;
      Totals.RegionCoverage += Function.RegionCoverage;
      Totals.LineCoverage += Function.LineCoverage;
      Totals.BranchCoverage += Function.BranchCoverage;
      render(Function, DC, OS);
    }
    if (Totals.ExecutionCount) {
      renderDivider(FunctionReportColumns, OS);
      OS << "\n";
      render(Totals, DC, OS);
    }
  }
}

void CoverageReport::prepareSingleFileReport(const StringRef Filename,
    const coverage::CoverageMapping *Coverage,
    const CoverageViewOptions &Options, const unsigned LCP,
    FileCoverageSummary *FileReport, const CoverageFilter *Filters) {
  for (const auto &Group : Coverage->getInstantiationGroups(Filename)) {
    std::vector<FunctionCoverageSummary> InstantiationSummaries;
    for (const coverage::FunctionRecord *F : Group.getInstantiations()) {
      if (!Filters->matches(*Coverage, *F))
        continue;
      auto InstantiationSummary = FunctionCoverageSummary::get(*Coverage, *F);
      FileReport->addInstantiation(InstantiationSummary);
      InstantiationSummaries.push_back(InstantiationSummary);
    }
    if (InstantiationSummaries.empty())
      continue;

    auto GroupSummary =
        FunctionCoverageSummary::get(Group, InstantiationSummaries);

    if (Options.Debug)
      outs() << "InstantiationGroup: " << GroupSummary.Name << " with "
             << "size = " << Group.size() << "\n";

    FileReport->addFunction(GroupSummary);
  }
}

std::vector<FileCoverageSummary> CoverageReport::prepareFileReports(
    const coverage::CoverageMapping &Coverage, FileCoverageSummary &Totals,
    ArrayRef<std::string> Files, const CoverageViewOptions &Options,
    const CoverageFilter &Filters) {
  unsigned LCP = getRedundantPrefixLen(Files);

  ThreadPoolStrategy S = hardware_concurrency(Options.NumThreads);
  if (Options.NumThreads == 0) {
    // If NumThreads is not specified, create one thread for each input, up to
    // the number of hardware cores.
    S = heavyweight_hardware_concurrency(Files.size());
    S.Limit = true;
  }
  ThreadPool Pool(S);

  std::vector<FileCoverageSummary> FileReports;
  FileReports.reserve(Files.size());

  for (StringRef Filename : Files) {
    FileReports.emplace_back(Filename.drop_front(LCP));
    Pool.async(&CoverageReport::prepareSingleFileReport, Filename,
               &Coverage, Options, LCP, &FileReports.back(), &Filters);
  }
  Pool.wait();

  for (const auto &FileReport : FileReports)
    Totals += FileReport;

  return FileReports;
}

void CoverageReport::renderFileReports(
    raw_ostream &OS, const CoverageFilters &IgnoreFilenameFilters) const {
  std::vector<std::string> UniqueSourceFiles;
  for (StringRef SF : Coverage.getUniqueSourceFiles()) {
    // Apply ignore source files filters.
    if (!IgnoreFilenameFilters.matchesFilename(SF))
      UniqueSourceFiles.emplace_back(SF.str());
  }
  renderFileReports(OS, UniqueSourceFiles);
}

void CoverageReport::renderFileReports(
    raw_ostream &OS, ArrayRef<std::string> Files) const {
  renderFileReports(OS, Files, CoverageFiltersMatchAll());
}

void CoverageReport::renderFileReports(
    raw_ostream &OS, ArrayRef<std::string> Files,
    const CoverageFiltersMatchAll &Filters) const {
  FileCoverageSummary Totals("TOTAL");
  auto FileReports =
      prepareFileReports(Coverage, Totals, Files, Options, Filters);

  std::vector<StringRef> Filenames;
  for (const FileCoverageSummary &FCS : FileReports)
    Filenames.emplace_back(FCS.Name);
  adjustColumnWidths(Filenames, {});

  OS << column("Filename", FileReportColumns[0]);
  if (Options.ShowRegionSummary)
    OS << column("Regions", FileReportColumns[1], Column::RightAlignment)
       << column("Missed Regions", FileReportColumns[2], Column::RightAlignment)
       << column("Cover", FileReportColumns[3], Column::RightAlignment);
  OS << column("Functions", FileReportColumns[4], Column::RightAlignment)
     << column("Missed Functions", FileReportColumns[5], Column::RightAlignment)
     << column("Executed", FileReportColumns[6], Column::RightAlignment);
  if (Options.ShowInstantiationSummary)
    OS << column("Instantiations", FileReportColumns[7], Column::RightAlignment)
       << column("Missed Insts.", FileReportColumns[8], Column::RightAlignment)
       << column("Executed", FileReportColumns[9], Column::RightAlignment);
  OS << column("Lines", FileReportColumns[10], Column::RightAlignment)
     << column("Missed Lines", FileReportColumns[11], Column::RightAlignment)
     << column("Cover", FileReportColumns[12], Column::RightAlignment);
  if (Options.ShowBranchSummary)
    OS << column("Branches", FileReportColumns[13], Column::RightAlignment)
       << column("Missed Branches", FileReportColumns[14],
                 Column::RightAlignment)
       << column("Cover", FileReportColumns[15], Column::RightAlignment);
  OS << "\n";
  renderDivider(FileReportColumns, OS);
  OS << "\n";

  bool EmptyFiles = false;
  for (const FileCoverageSummary &FCS : FileReports) {
    if (FCS.FunctionCoverage.getNumFunctions())
      render(FCS, OS);
    else
      EmptyFiles = true;
  }

  if (EmptyFiles && Filters.empty()) {
    OS << "\n"
       << "Files which contain no functions:\n";

    for (const FileCoverageSummary &FCS : FileReports)
      if (!FCS.FunctionCoverage.getNumFunctions())
        render(FCS, OS);
  }

  renderDivider(FileReportColumns, OS);
  OS << "\n";
  render(Totals, OS);
}

} // end namespace llvm
