//===- SourceCoverageViewText.cpp - A text-based code coverage view -------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file This file implements the text-based coverage renderer.
///
//===----------------------------------------------------------------------===//

#include "SourceCoverageViewText.h"
#include "CoverageReport.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include <optional>

using namespace llvm;

Expected<CoveragePrinter::OwnedStream>
CoveragePrinterText::createViewFile(StringRef Path, bool InToplevel) {
  return createOutputStream(Path, "txt", InToplevel);
}

void CoveragePrinterText::closeViewFile(OwnedStream OS) {
  OS->operator<<('\n');
}

Error CoveragePrinterText::createIndexFile(
    ArrayRef<std::string> SourceFiles, const CoverageMapping &Coverage,
    const CoverageFiltersMatchAll &Filters) {
  auto OSOrErr = createOutputStream("index", "txt", /*InToplevel=*/true);
  if (Error E = OSOrErr.takeError())
    return E;
  auto OS = std::move(OSOrErr.get());
  raw_ostream &OSRef = *OS.get();

  CoverageReport Report(Opts, Coverage);
  Report.renderFileReports(OSRef, SourceFiles, Filters);

  Opts.colored_ostream(OSRef, raw_ostream::CYAN) << "\n"
                                                 << Opts.getLLVMVersionString();

  return Error::success();
}

struct CoveragePrinterTextDirectory::Reporter : public DirectoryCoverageReport {
  CoveragePrinterTextDirectory &Printer;

  Reporter(CoveragePrinterTextDirectory &Printer,
           const coverage::CoverageMapping &Coverage,
           const CoverageFiltersMatchAll &Filters)
      : DirectoryCoverageReport(Printer.Opts, Coverage, Filters),
        Printer(Printer) {}

  Error generateSubDirectoryReport(SubFileReports &&SubFiles,
                                   SubDirReports &&SubDirs,
                                   FileCoverageSummary &&SubTotals) override {
    auto &LCPath = SubTotals.Name;
    assert(Options.hasOutputDirectory() &&
           "No output directory for index file");

    SmallString<128> OSPath = LCPath;
    sys::path::append(OSPath, "index");
    auto OSOrErr = Printer.createOutputStream(OSPath, "txt",
                                              /*InToplevel=*/false);
    if (auto E = OSOrErr.takeError())
      return E;
    auto OS = std::move(OSOrErr.get());
    raw_ostream &OSRef = *OS.get();

    std::vector<FileCoverageSummary> Reports;
    for (auto &&SubDir : SubDirs)
      Reports.push_back(std::move(SubDir.second.first));
    for (auto &&SubFile : SubFiles)
      Reports.push_back(std::move(SubFile.second));

    CoverageReport Report(Options, Coverage);
    Report.renderFileReports(OSRef, Reports, SubTotals, Filters.empty());

    Options.colored_ostream(OSRef, raw_ostream::CYAN)
        << "\n"
        << Options.getLLVMVersionString();

    return Error::success();
  }
};

Error CoveragePrinterTextDirectory::createIndexFile(
    ArrayRef<std::string> SourceFiles, const CoverageMapping &Coverage,
    const CoverageFiltersMatchAll &Filters) {
  if (SourceFiles.size() <= 1)
    return CoveragePrinterText::createIndexFile(SourceFiles, Coverage, Filters);

  Reporter Report(*this, Coverage, Filters);
  auto TotalsOrErr = Report.prepareDirectoryReports(SourceFiles);
  if (auto E = TotalsOrErr.takeError())
    return E;
  auto &LCPath = TotalsOrErr->Name;

  auto TopIndexFilePath =
      getOutputPath("index", "txt", /*InToplevel=*/true, /*Relative=*/false);
  auto LCPIndexFilePath =
      getOutputPath((LCPath + "index").str(), "txt", /*InToplevel=*/false,
                    /*Relative=*/false);
  return errorCodeToError(
      sys::fs::copy_file(LCPIndexFilePath, TopIndexFilePath));
}

namespace {

static const unsigned LineCoverageColumnWidth = 7;
static const unsigned LineNumberColumnWidth = 5;

/// Get the width of the leading columns.
unsigned getCombinedColumnWidth(const CoverageViewOptions &Opts) {
  return (Opts.ShowLineStats ? LineCoverageColumnWidth + 1 : 0) +
         (Opts.ShowLineNumbers ? LineNumberColumnWidth + 1 : 0);
}

/// The width of the line that is used to divide between the view and
/// the subviews.
unsigned getDividerWidth(const CoverageViewOptions &Opts) {
  return getCombinedColumnWidth(Opts) + 4;
}

} // anonymous namespace

void SourceCoverageViewText::renderViewHeader(raw_ostream &) {}

void SourceCoverageViewText::renderViewFooter(raw_ostream &) {}

void SourceCoverageViewText::renderSourceName(raw_ostream &OS, bool WholeFile) {
  getOptions().colored_ostream(OS, raw_ostream::CYAN) << getSourceName()
                                                      << ":\n";
}

void SourceCoverageViewText::renderLinePrefix(raw_ostream &OS,
                                              unsigned ViewDepth) {
  for (unsigned I = 0; I < ViewDepth; ++I)
    OS << "  |";
}

void SourceCoverageViewText::renderLineSuffix(raw_ostream &, unsigned) {}

void SourceCoverageViewText::renderViewDivider(raw_ostream &OS,
                                               unsigned ViewDepth) {
  assert(ViewDepth != 0 && "Cannot render divider at top level");
  renderLinePrefix(OS, ViewDepth - 1);
  OS.indent(2);
  unsigned Length = getDividerWidth(getOptions());
  for (unsigned I = 0; I < Length; ++I)
    OS << '-';
  OS << '\n';
}

void SourceCoverageViewText::renderLine(raw_ostream &OS, LineRef L,
                                        const LineCoverageStats &LCS,
                                        unsigned ExpansionCol,
                                        unsigned ViewDepth) {
  StringRef Line = L.Line;
  unsigned LineNumber = L.LineNo;
  auto *WrappedSegment = LCS.getWrappedSegment();
  CoverageSegmentArray Segments = LCS.getLineSegments();

  std::optional<raw_ostream::Colors> Highlight;
  SmallVector<std::pair<unsigned, unsigned>, 2> HighlightedRanges;

  // The first segment overlaps from a previous line, so we treat it specially.
  if (WrappedSegment && !WrappedSegment->IsGapRegion &&
      WrappedSegment->HasCount && WrappedSegment->Count == 0)
    Highlight = raw_ostream::RED;

  // Output each segment of the line, possibly highlighted.
  unsigned Col = 1;
  for (const auto *S : Segments) {
    unsigned End = std::min(S->Col, static_cast<unsigned>(Line.size()) + 1);
    colored_ostream(OS, Highlight.value_or(raw_ostream::SAVEDCOLOR),
                    getOptions().Colors && Highlight, /*Bold=*/false,
                    /*BG=*/true)
        << Line.substr(Col - 1, End - Col);
    if (getOptions().Debug && Highlight)
      HighlightedRanges.push_back(std::make_pair(Col, End));
    Col = End;
    if ((!S->IsGapRegion || Highlight == raw_ostream::RED) && S->HasCount &&
        S->Count == 0)
      Highlight = raw_ostream::RED;
    else if (Col == ExpansionCol)
      Highlight = raw_ostream::CYAN;
    else
      Highlight = std::nullopt;
  }

  // Show the rest of the line.
  colored_ostream(OS, Highlight.value_or(raw_ostream::SAVEDCOLOR),
                  getOptions().Colors && Highlight, /*Bold=*/false, /*BG=*/true)
      << Line.substr(Col - 1, Line.size() - Col + 1);
  OS << '\n';

  if (getOptions().Debug) {
    for (const auto &Range : HighlightedRanges)
      errs() << "Highlighted line " << LineNumber << ", " << Range.first
             << " -> " << Range.second << '\n';
    if (Highlight)
      errs() << "Highlighted line " << LineNumber << ", " << Col << " -> ?\n";
  }
}

void SourceCoverageViewText::renderLineCoverageColumn(
    raw_ostream &OS, const LineCoverageStats &Line) {
  if (!Line.isMapped()) {
    OS.indent(LineCoverageColumnWidth) << '|';
    return;
  }
  std::string C = formatBinaryCount(Line.getExecutionCount());
  OS.indent(LineCoverageColumnWidth - C.size());
  colored_ostream(OS, raw_ostream::MAGENTA,
                  Line.hasMultipleRegions() && getOptions().Colors)
      << C;
  OS << '|';
}

void SourceCoverageViewText::renderLineNumberColumn(raw_ostream &OS,
                                                    unsigned LineNo) {
  SmallString<32> Buffer;
  raw_svector_ostream BufferOS(Buffer);
  BufferOS << LineNo;
  auto Str = BufferOS.str();
  // Trim and align to the right.
  Str = Str.substr(0, std::min(Str.size(), (size_t)LineNumberColumnWidth));
  OS.indent(LineNumberColumnWidth - Str.size()) << Str << '|';
}

void SourceCoverageViewText::renderRegionMarkers(raw_ostream &OS,
                                                 const LineCoverageStats &Line,
                                                 unsigned ViewDepth) {
  renderLinePrefix(OS, ViewDepth);
  OS.indent(getCombinedColumnWidth(getOptions()));

  CoverageSegmentArray Segments = Line.getLineSegments();

  // Just consider the segments which start *and* end on this line.
  if (Segments.size() > 1)
    Segments = Segments.drop_back();

  unsigned PrevColumn = 1;
  for (const auto *S : Segments) {
    if (!S->IsRegionEntry)
      continue;
    if (S->Count == Line.getExecutionCount())
      continue;
    // Skip to the new region.
    if (S->Col > PrevColumn)
      OS.indent(S->Col - PrevColumn);
    PrevColumn = S->Col + 1;
    std::string C = formatCount(S->Count);
    PrevColumn += C.size();
    OS << '^' << C;

    if (getOptions().Debug)
      errs() << "Marker at " << S->Line << ":" << S->Col << " = "
             << formatBinaryCount(S->Count) << "\n";
  }
  OS << '\n';
}

void SourceCoverageViewText::renderExpansionSite(raw_ostream &OS, LineRef L,
                                                 const LineCoverageStats &LCS,
                                                 unsigned ExpansionCol,
                                                 unsigned ViewDepth) {
  renderLinePrefix(OS, ViewDepth);
  OS.indent(getCombinedColumnWidth(getOptions()) + (ViewDepth == 0 ? 0 : 1));
  renderLine(OS, L, LCS, ExpansionCol, ViewDepth);
}

void SourceCoverageViewText::renderExpansionView(raw_ostream &OS,
                                                 ExpansionView &ESV,
                                                 unsigned ViewDepth) {
  // Render the child subview.
  if (getOptions().Debug)
    errs() << "Expansion at line " << ESV.getLine() << ", " << ESV.getStartCol()
           << " -> " << ESV.getEndCol() << '\n';
  ESV.View->print(OS, /*WholeFile=*/false, /*ShowSourceName=*/false,
                  /*ShowTitle=*/false, ViewDepth + 1);
}

void SourceCoverageViewText::renderBranchView(raw_ostream &OS, BranchView &BRV,
                                              unsigned ViewDepth) {
  // Render the child subview.
  if (getOptions().Debug)
    errs() << "Branch at line " << BRV.getLine() << '\n';

  auto BranchCount = [&](StringRef Label, uint64_t Count, bool Folded,
                         double Total) {
    if (Folded)
      return std::string{"Folded"};

    std::string Str;
    raw_string_ostream OS(Str);

    colored_ostream(OS, raw_ostream::RED, getOptions().Colors && !Count,
                    /*Bold=*/false, /*BG=*/true)
        << Label;

    if (getOptions().ShowBranchCounts)
      OS << ": " << formatBinaryCount(Count);
    else
      OS << ": " << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0))
         << "%";

    return Str;
  };

  for (const auto &R : BRV.Regions) {
    // This can be `double` since it is only used as a denominator.
    // FIXME: It is still inaccurate if Count is greater than (1LL << 53).
    double Total =
        static_cast<double>(R.ExecutionCount) + R.FalseExecutionCount;

    renderLinePrefix(OS, ViewDepth);
    OS << "  Branch (" << R.LineStart << ":" << R.ColumnStart << "): [";

    if (R.TrueFolded && R.FalseFolded) {
      OS << "Folded - Ignored]\n";
      continue;
    }

    OS << BranchCount("True", R.ExecutionCount, R.TrueFolded, Total) << ", "
       << BranchCount("False", R.FalseExecutionCount, R.FalseFolded, Total)
       << "]\n";
  }
}

void SourceCoverageViewText::renderMCDCView(raw_ostream &OS, MCDCView &MRV,
                                            unsigned ViewDepth) {
  for (auto &Record : MRV.Records) {
    renderLinePrefix(OS, ViewDepth);
    OS << "---> MC/DC Decision Region (";
    // Display Line + Column information.
    const CounterMappingRegion &DecisionRegion = Record.getDecisionRegion();
    OS << DecisionRegion.LineStart << ":";
    OS << DecisionRegion.ColumnStart << ") to (";
    OS << DecisionRegion.LineEnd << ":";
    OS << DecisionRegion.ColumnEnd << ")\n";
    renderLinePrefix(OS, ViewDepth);
    OS << "\n";

    // Display MC/DC Information.
    renderLinePrefix(OS, ViewDepth);
    OS << "  Number of Conditions: " << Record.getNumConditions() << "\n";
    for (unsigned i = 0; i < Record.getNumConditions(); i++) {
      renderLinePrefix(OS, ViewDepth);
      OS << "     " << Record.getConditionHeaderString(i);
    }
    renderLinePrefix(OS, ViewDepth);
    OS << "\n";
    renderLinePrefix(OS, ViewDepth);
    OS << "  Executed MC/DC Test Vectors:\n";
    renderLinePrefix(OS, ViewDepth);
    OS << "\n";
    renderLinePrefix(OS, ViewDepth);
    OS << "     ";
    OS << Record.getTestVectorHeaderString();
    for (unsigned i = 0; i < Record.getNumTestVectors(); i++) {
      renderLinePrefix(OS, ViewDepth);
      OS << Record.getTestVectorString(i);
    }
    renderLinePrefix(OS, ViewDepth);
    OS << "\n";
    for (unsigned i = 0; i < Record.getNumConditions(); i++) {
      renderLinePrefix(OS, ViewDepth);
      OS << Record.getConditionCoverageString(i);
    }
    renderLinePrefix(OS, ViewDepth);
    OS << "  MC/DC Coverage for Decision: ";
    colored_ostream(OS, raw_ostream::RED,
                    getOptions().Colors && Record.getPercentCovered() < 100.0,
                    /*Bold=*/false, /*BG=*/true)
        << format("%0.2f", Record.getPercentCovered()) << "%";
    OS << "\n";
    renderLinePrefix(OS, ViewDepth);
    OS << "\n";
  }
}

void SourceCoverageViewText::renderInstantiationView(raw_ostream &OS,
                                                     InstantiationView &ISV,
                                                     unsigned ViewDepth) {
  renderLinePrefix(OS, ViewDepth);
  OS << ' ';
  if (!ISV.View)
    getOptions().colored_ostream(OS, raw_ostream::RED)
        << "Unexecuted instantiation: " << ISV.FunctionName << "\n";
  else
    ISV.View->print(OS, /*WholeFile=*/false, /*ShowSourceName=*/true,
                    /*ShowTitle=*/false, ViewDepth);
}

void SourceCoverageViewText::renderTitle(raw_ostream &OS, StringRef Title) {
  if (getOptions().hasProjectTitle())
    getOptions().colored_ostream(OS, raw_ostream::CYAN)
        << getOptions().ProjectTitle << "\n";

  getOptions().colored_ostream(OS, raw_ostream::CYAN) << Title << "\n";

  if (getOptions().hasCreatedTime())
    getOptions().colored_ostream(OS, raw_ostream::CYAN)
        << getOptions().CreatedTimeStr << "\n";
}

void SourceCoverageViewText::renderTableHeader(raw_ostream &, unsigned) {}
