//===-- DiagnosticsRendering.cpp ------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "lldb/Utility/DiagnosticsRendering.h"

using namespace lldb_private;
using namespace lldb;

namespace lldb_private {

char DiagnosticError::ID;

lldb::ErrorType DiagnosticError::GetErrorType() const {
  return lldb::eErrorTypeExpression;
}

static llvm::raw_ostream &PrintSeverity(Stream &stream,
                                        lldb::Severity severity) {
  llvm::HighlightColor color;
  llvm::StringRef text;
  switch (severity) {
  case lldb::eSeverityError:
    color = llvm::HighlightColor::Error;
    text = "error: ";
    break;
  case lldb::eSeverityWarning:
    color = llvm::HighlightColor::Warning;
    text = "warning: ";
    break;
  case lldb::eSeverityInfo:
    color = llvm::HighlightColor::Remark;
    text = "note: ";
    break;
  }
  return llvm::WithColor(stream.AsRawOstream(), color, llvm::ColorMode::Enable)
         << text;
}

void RenderDiagnosticDetails(Stream &stream,
                             std::optional<uint16_t> offset_in_command,
                             bool show_inline,
                             llvm::ArrayRef<DiagnosticDetail> details) {
  if (details.empty())
    return;

  if (!offset_in_command) {
    for (const DiagnosticDetail &detail : details) {
      PrintSeverity(stream, detail.severity);
      stream << detail.rendered << '\n';
    }
    return;
  }

  // Since there is no other way to find this out, use the color
  // attribute as a proxy for whether the terminal supports Unicode
  // characters.  In the future it might make sense to move this into
  // Host so it can be customized for a specific platform.
  llvm::StringRef cursor, underline, vbar, joint, hbar, spacer;
  if (stream.AsRawOstream().colors_enabled()) {
    cursor = "˄";
    underline = "˜";
    vbar = "│";
    joint = "╰";
    hbar = "─";
    spacer = " ";
  } else {
    cursor = "^";
    underline = "~";
    vbar = "|";
    joint = "";
    hbar = "";
    spacer = "";
  }

  // Partition the diagnostics.
  std::vector<DiagnosticDetail> remaining_details, other_details,
      hidden_details;
  for (const DiagnosticDetail &detail : details) {
    if (!show_inline || !detail.source_location) {
      other_details.push_back(detail);
      continue;
    }
    if (detail.source_location->hidden) {
      hidden_details.push_back(detail);
      continue;
    }
    if (!detail.source_location->in_user_input) {
      other_details.push_back(detail);
      continue;
    }

    remaining_details.push_back(detail);
  }

  // Sort the diagnostics.
  auto sort = [](auto &ds) {
    std::stable_sort(ds.begin(), ds.end(), [](auto &d1, auto &d2) {
      auto l1 = d1.source_location.value_or(DiagnosticDetail::SourceLocation{});
      auto l2 = d2.source_location.value_or(DiagnosticDetail::SourceLocation{});
      return std::tie(l1.line, l1.column) < std::tie(l2.line, l2.column);
    });
  };
  sort(remaining_details);
  sort(other_details);
  sort(hidden_details);

  // Print a line with caret indicator(s) below the lldb prompt + command.
  const size_t padding = *offset_in_command;
  stream << std::string(padding, ' ');
  {
    size_t x_pos = 1;
    for (const DiagnosticDetail &detail : remaining_details) {
      auto &loc = *detail.source_location;

      if (x_pos > loc.column)
        continue;

      stream << std::string(loc.column - x_pos, ' ') << cursor;
      ++x_pos;
      for (unsigned i = 0; i + 1 < loc.length; ++i) {
        stream << underline;
        ++x_pos;
      }
    }
  }
  stream << '\n';

  // Work through each detail in reverse order using the vector/stack.
  bool did_print = false;
  for (auto detail = remaining_details.rbegin();
       detail != remaining_details.rend();
       ++detail, remaining_details.pop_back()) {
    // Get the information to print this detail and remove it from the stack.
    // Print all the lines for all the other messages first.
    stream << std::string(padding, ' ');
    size_t x_pos = 1;
    for (auto &remaining_detail :
         llvm::ArrayRef(remaining_details).drop_back(1)) {
      uint16_t column = remaining_detail.source_location->column;
      if (x_pos <= column)
        stream << std::string(column - x_pos, ' ') << vbar;
      x_pos = column + 1;
    }

    // Print the line connecting the ^ with the error message.
    uint16_t column = detail->source_location->column;
    if (x_pos <= column)
      stream << std::string(column - x_pos, ' ') << joint << hbar << spacer;

    // Print a colorized string based on the message's severity type.
    PrintSeverity(stream, detail->severity);

    // Finally, print the message and start a new line.
    stream << detail->message << '\n';
    did_print = true;
  }

  // Print the non-located details.
  for (const DiagnosticDetail &detail : other_details) {
    PrintSeverity(stream, detail.severity);
    stream << detail.rendered << '\n';
    did_print = true;
  }

  // Print the hidden details as a last resort.
  if (!did_print)
    for (const DiagnosticDetail &detail : hidden_details) {
      PrintSeverity(stream, detail.severity);
      stream << detail.rendered << '\n';
    }
}

} // namespace lldb_private
