//===- SourceCoverageView.cpp - Code coverage view for source code --------===//
//
// 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 class implements rendering for code coverage of source code.
///
//===----------------------------------------------------------------------===//

#include "SourceCoverageView.h"
#include "SourceCoverageViewHTML.h"
#include "SourceCoverageViewText.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/Path.h"

using namespace llvm;

void CoveragePrinter::StreamDestructor::operator()(raw_ostream *OS) const {
  if (OS == &outs())
    return;
  delete OS;
}

std::string CoveragePrinter::getOutputPath(StringRef Path, StringRef Extension,
                                           bool InToplevel,
                                           bool Relative) const {
  assert(!Extension.empty() && "The file extension may not be empty");

  SmallString<256> FullPath;

  if (!Relative)
    FullPath.append(Opts.ShowOutputDirectory);

  if (!InToplevel)
    sys::path::append(FullPath, getCoverageDir());

  SmallString<256> ParentPath = sys::path::parent_path(Path);
  sys::path::remove_dots(ParentPath, /*remove_dot_dot=*/true);
  sys::path::append(FullPath, sys::path::relative_path(ParentPath));

  auto PathFilename = (sys::path::filename(Path) + "." + Extension).str();
  sys::path::append(FullPath, PathFilename);
  sys::path::native(FullPath);

  return std::string(FullPath);
}

Expected<CoveragePrinter::OwnedStream>
CoveragePrinter::createOutputStream(StringRef Path, StringRef Extension,
                                    bool InToplevel) const {
  if (!Opts.hasOutputDirectory())
    return OwnedStream(&outs());

  std::string FullPath = getOutputPath(Path, Extension, InToplevel, false);

  auto ParentDir = sys::path::parent_path(FullPath);
  if (auto E = sys::fs::create_directories(ParentDir))
    return errorCodeToError(E);

  std::error_code E;
  raw_ostream *RawStream =
      new raw_fd_ostream(FullPath, E, sys::fs::FA_Read | sys::fs::FA_Write);
  auto OS = CoveragePrinter::OwnedStream(RawStream);
  if (E)
    return errorCodeToError(E);
  return std::move(OS);
}

std::unique_ptr<CoveragePrinter>
CoveragePrinter::create(const CoverageViewOptions &Opts) {
  switch (Opts.Format) {
  case CoverageViewOptions::OutputFormat::Text:
    if (Opts.ShowDirectoryCoverage)
      return std::make_unique<CoveragePrinterTextDirectory>(Opts);
    return std::make_unique<CoveragePrinterText>(Opts);
  case CoverageViewOptions::OutputFormat::HTML:
    if (Opts.ShowDirectoryCoverage)
      return std::make_unique<CoveragePrinterHTMLDirectory>(Opts);
    return std::make_unique<CoveragePrinterHTML>(Opts);
  case CoverageViewOptions::OutputFormat::Lcov:
    // Unreachable because CodeCoverage.cpp should terminate with an error
    // before we get here.
    llvm_unreachable("Lcov format is not supported!");
  }
  llvm_unreachable("Unknown coverage output format!");
}

unsigned SourceCoverageView::getFirstUncoveredLineNo() {
  const auto MinSegIt = find_if(CoverageInfo, [](const CoverageSegment &S) {
    return S.HasCount && S.Count == 0;
  });

  // There is no uncovered line, return zero.
  if (MinSegIt == CoverageInfo.end())
    return 0;

  return (*MinSegIt).Line;
}

std::string SourceCoverageView::formatCount(uint64_t N) {
  std::string Number = utostr(N);
  int Len = Number.size();
  if (Len <= 3)
    return Number;
  int IntLen = Len % 3 == 0 ? 3 : Len % 3;
  std::string Result(Number.data(), IntLen);
  if (IntLen != 3) {
    Result.push_back('.');
    Result += Number.substr(IntLen, 3 - IntLen);
  }
  Result.push_back(" kMGTPEZY"[(Len - 1) / 3]);
  return Result;
}

bool SourceCoverageView::shouldRenderRegionMarkers(
    const LineCoverageStats &LCS) const {
  if (!getOptions().ShowRegionMarkers)
    return false;

  CoverageSegmentArray Segments = LCS.getLineSegments();
  if (Segments.empty())
    return false;
  for (unsigned I = 0, E = Segments.size() - 1; I < E; ++I) {
    const auto *CurSeg = Segments[I];
    if (!CurSeg->IsRegionEntry || CurSeg->Count == LCS.getExecutionCount())
      continue;
    if (!CurSeg->HasCount) // don't show tooltips for SkippedRegions
      continue;
    return true;
  }
  return false;
}

bool SourceCoverageView::hasSubViews() const {
  return !ExpansionSubViews.empty() || !InstantiationSubViews.empty() ||
         !BranchSubViews.empty() || !MCDCSubViews.empty();
}

std::unique_ptr<SourceCoverageView>
SourceCoverageView::create(StringRef SourceName, const MemoryBuffer &File,
                           const CoverageViewOptions &Options,
                           CoverageData &&CoverageInfo) {
  switch (Options.Format) {
  case CoverageViewOptions::OutputFormat::Text:
    return std::make_unique<SourceCoverageViewText>(
        SourceName, File, Options, std::move(CoverageInfo));
  case CoverageViewOptions::OutputFormat::HTML:
    return std::make_unique<SourceCoverageViewHTML>(
        SourceName, File, Options, std::move(CoverageInfo));
  case CoverageViewOptions::OutputFormat::Lcov:
    // Unreachable because CodeCoverage.cpp should terminate with an error
    // before we get here.
    llvm_unreachable("Lcov format is not supported!");
  }
  llvm_unreachable("Unknown coverage output format!");
}

std::string SourceCoverageView::getSourceName() const {
  SmallString<128> SourceText(SourceName);
  sys::path::remove_dots(SourceText, /*remove_dot_dot=*/true);
  sys::path::native(SourceText);
  return std::string(SourceText);
}

void SourceCoverageView::addExpansion(
    const CounterMappingRegion &Region,
    std::unique_ptr<SourceCoverageView> View) {
  ExpansionSubViews.emplace_back(Region, std::move(View));
}

void SourceCoverageView::addBranch(unsigned Line,
                                   SmallVector<CountedRegion, 0> Regions,
                                   std::unique_ptr<SourceCoverageView> View) {
  BranchSubViews.emplace_back(Line, std::move(Regions), std::move(View));
}

void SourceCoverageView::addMCDCRecord(
    unsigned Line, SmallVector<MCDCRecord, 0> Records,
    std::unique_ptr<SourceCoverageView> View) {
  MCDCSubViews.emplace_back(Line, std::move(Records), std::move(View));
}

void SourceCoverageView::addInstantiation(
    StringRef FunctionName, unsigned Line,
    std::unique_ptr<SourceCoverageView> View) {
  InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View));
}

void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
                               bool ShowSourceName, bool ShowTitle,
                               unsigned ViewDepth) {
  if (ShowTitle)
    renderTitle(OS, "Coverage Report");

  renderViewHeader(OS);

  if (ShowSourceName)
    renderSourceName(OS, WholeFile);

  renderTableHeader(OS, (ViewDepth > 0) ? 0 : getFirstUncoveredLineNo(),
                    ViewDepth);

  // We need the expansions, instantiations, and branches sorted so we can go
  // through them while we iterate lines.
  llvm::stable_sort(ExpansionSubViews);
  llvm::stable_sort(InstantiationSubViews);
  llvm::stable_sort(BranchSubViews);
  llvm::stable_sort(MCDCSubViews);
  auto NextESV = ExpansionSubViews.begin();
  auto EndESV = ExpansionSubViews.end();
  auto NextISV = InstantiationSubViews.begin();
  auto EndISV = InstantiationSubViews.end();
  auto NextBRV = BranchSubViews.begin();
  auto EndBRV = BranchSubViews.end();
  auto NextMSV = MCDCSubViews.begin();
  auto EndMSV = MCDCSubViews.end();

  // Get the coverage information for the file.
  auto StartSegment = CoverageInfo.begin();
  auto EndSegment = CoverageInfo.end();
  LineCoverageIterator LCI{CoverageInfo, 1};
  LineCoverageIterator LCIEnd = LCI.getEnd();

  unsigned FirstLine = StartSegment != EndSegment ? StartSegment->Line : 0;
  for (line_iterator LI(File, /*SkipBlanks=*/false); !LI.is_at_eof();
       ++LI, ++LCI) {
    // If we aren't rendering the whole file, we need to filter out the prologue
    // and epilogue.
    if (!WholeFile) {
      if (LCI == LCIEnd)
        break;
      else if (LI.line_number() < FirstLine)
        continue;
    }

    renderLinePrefix(OS, ViewDepth);
    if (getOptions().ShowLineNumbers)
      renderLineNumberColumn(OS, LI.line_number());

    if (getOptions().ShowLineStats)
      renderLineCoverageColumn(OS, *LCI);

    // If there are expansion subviews, we want to highlight the first one.
    unsigned ExpansionColumn = 0;
    if (NextESV != EndESV && NextESV->getLine() == LI.line_number() &&
        getOptions().Colors)
      ExpansionColumn = NextESV->getStartCol();

    // Display the source code for the current line.
    renderLine(OS, {*LI, LI.line_number()}, *LCI, ExpansionColumn, ViewDepth);

    // Show the region markers.
    if (shouldRenderRegionMarkers(*LCI))
      renderRegionMarkers(OS, *LCI, ViewDepth);

    // Show the expansions, instantiations, and branches for this line.
    bool RenderedSubView = false;
    for (; NextESV != EndESV && NextESV->getLine() == LI.line_number();
         ++NextESV) {
      renderViewDivider(OS, ViewDepth + 1);

      // Re-render the current line and highlight the expansion range for
      // this subview.
      if (RenderedSubView) {
        ExpansionColumn = NextESV->getStartCol();
        renderExpansionSite(OS, {*LI, LI.line_number()}, *LCI, ExpansionColumn,
                            ViewDepth);
        renderViewDivider(OS, ViewDepth + 1);
      }

      renderExpansionView(OS, *NextESV, ViewDepth + 1);
      RenderedSubView = true;
    }
    for (; NextISV != EndISV && NextISV->Line == LI.line_number(); ++NextISV) {
      renderViewDivider(OS, ViewDepth + 1);
      renderInstantiationView(OS, *NextISV, ViewDepth + 1);
      RenderedSubView = true;
    }
    for (; NextBRV != EndBRV && NextBRV->Line == LI.line_number(); ++NextBRV) {
      renderViewDivider(OS, ViewDepth + 1);
      renderBranchView(OS, *NextBRV, ViewDepth + 1);
      RenderedSubView = true;
    }
    for (; NextMSV != EndMSV && NextMSV->Line == LI.line_number(); ++NextMSV) {
      renderViewDivider(OS, ViewDepth + 1);
      renderMCDCView(OS, *NextMSV, ViewDepth + 1);
      RenderedSubView = true;
    }
    if (RenderedSubView)
      renderViewDivider(OS, ViewDepth + 1);
    renderLineSuffix(OS, ViewDepth);
  }

  renderViewFooter(OS);
}
