//===-- DiagnosticManager.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/Expression/DiagnosticManager.h"

#include "llvm/Support/ErrorHandling.h"

#include "lldb/Utility/ErrorMessages.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb_private;
char ExpressionError::ID;

/// A std::error_code category for eErrorTypeExpression.
class ExpressionCategory : public std::error_category {
  const char *name() const noexcept override {
    return "LLDBExpressionCategory";
  }
  std::string message(int __ev) const override {
    return toString(static_cast<lldb::ExpressionResults>(__ev));
  };
};
ExpressionCategory &expression_category() {
  static ExpressionCategory g_expression_category;
  return g_expression_category;
}

ExpressionError::ExpressionError(lldb::ExpressionResults result,
                                 std::string msg,
                                 std::vector<DiagnosticDetail> details)
    : ErrorInfo(std::error_code(result, expression_category())), m_message(msg),
      m_details(details) {}

static llvm::StringRef StringForSeverity(lldb::Severity severity) {
  switch (severity) {
  // this should be exhaustive
  case lldb::eSeverityError:
    return "error: ";
  case lldb::eSeverityWarning:
    return "warning: ";
  case lldb::eSeverityInfo:
    return "";
  }
  llvm_unreachable("switch needs another case for lldb::Severity enum");
}

std::string ExpressionError::message() const {
  std::string str;
  {
    llvm::raw_string_ostream os(str);
    if (!m_message.empty())
      os << m_message << '\n';
    for (const auto &detail : m_details)
      os << StringForSeverity(detail.severity) << detail.rendered << '\n';
  }
  return str;
}

std::error_code ExpressionError::convertToErrorCode() const {
  return llvm::inconvertibleErrorCode();
}

void ExpressionError::log(llvm::raw_ostream &OS) const { OS << message(); }

std::unique_ptr<CloneableError> ExpressionError::Clone() const {
  return std::make_unique<ExpressionError>(
      (lldb::ExpressionResults)convertToErrorCode().value(), m_message,
      m_details);
}

std::string DiagnosticManager::GetString(char separator) {
  std::string str;
  llvm::raw_string_ostream stream(str);

  for (const auto &diagnostic : Diagnostics()) {
    llvm::StringRef severity = StringForSeverity(diagnostic->GetSeverity());
    stream << severity;

    llvm::StringRef message = diagnostic->GetMessage();
    auto severity_pos = message.find(severity);
    stream << message.take_front(severity_pos);

    if (severity_pos != llvm::StringRef::npos)
      stream << message.drop_front(severity_pos + severity.size());
    stream << separator;
  }
  return str;
}

void DiagnosticManager::Dump(Log *log) {
  if (!log)
    return;

  std::string str = GetString();

  // We want to remove the last '\n' because log->PutCString will add
  // one for us.

  if (!str.empty() && str.back() == '\n')
    str.pop_back();

  log->PutString(str);
}

llvm::Error DiagnosticManager::GetAsError(lldb::ExpressionResults result,
                                          llvm::Twine message) const {
  std::vector<DiagnosticDetail> details;
  for (const auto &diag : m_diagnostics)
    details.push_back(diag->GetDetail());
  return llvm::make_error<ExpressionError>(result, message.str(), details);
}

void DiagnosticManager::AddDiagnostic(llvm::StringRef message,
                                      lldb::Severity severity,
                                      DiagnosticOrigin origin,
                                      uint32_t compiler_id) {
  m_diagnostics.emplace_back(std::make_unique<Diagnostic>(
      origin, compiler_id,
      DiagnosticDetail{{}, severity, message.str(), message.str()}));
}

size_t DiagnosticManager::Printf(lldb::Severity severity, const char *format,
                                 ...) {
  StreamString ss;

  va_list args;
  va_start(args, format);
  size_t result = ss.PrintfVarArg(format, args);
  va_end(args);

  AddDiagnostic(ss.GetString(), severity, eDiagnosticOriginLLDB);

  return result;
}

void DiagnosticManager::PutString(lldb::Severity severity,
                                  llvm::StringRef str) {
  if (str.empty())
    return;
  AddDiagnostic(str, severity, eDiagnosticOriginLLDB);
}

void Diagnostic::AppendMessage(llvm::StringRef message,
                               bool precede_with_newline) {
  if (precede_with_newline) {
    m_detail.message.push_back('\n');
    m_detail.rendered.push_back('\n');
  }
  m_detail.message += message;
  m_detail.rendered += message;
}
