//===- Diagnostic.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 "Diagnostics.h"
#include "mlir/Query/Matcher/ErrorBuilder.h"

namespace mlir::query::matcher::internal {

Diagnostics::ArgStream &
Diagnostics::ArgStream::operator<<(const llvm::Twine &arg) {
  out->push_back(arg.str());
  return *this;
}

Diagnostics::ArgStream Diagnostics::addError(SourceRange range,
                                             ErrorType error) {
  errorValues.emplace_back();
  ErrorContent &last = errorValues.back();
  last.contextStack = contextStack;
  last.messages.emplace_back();
  last.messages.back().range = range;
  last.messages.back().type = error;
  return ArgStream(&last.messages.back().args);
}

static llvm::StringRef errorTypeToFormatString(ErrorType type) {
  switch (type) {
  case ErrorType::RegistryMatcherNotFound:
    return "Matcher not found: $0";
  case ErrorType::RegistryWrongArgCount:
    return "Incorrect argument count. (Expected = $0) != (Actual = $1)";
  case ErrorType::RegistryWrongArgType:
    return "Incorrect type for arg $0. (Expected = $1) != (Actual = $2)";
  case ErrorType::RegistryValueNotFound:
    return "Value not found: $0";
  case ErrorType::RegistryNotBindable:
    return "Matcher does not support binding.";

  case ErrorType::ParserStringError:
    return "Error parsing string token: <$0>";
  case ErrorType::ParserNoOpenParen:
    return "Error parsing matcher. Found token <$0> while looking for '('.";
  case ErrorType::ParserNoCloseParen:
    return "Error parsing matcher. Found end-of-code while looking for ')'.";
  case ErrorType::ParserNoComma:
    return "Error parsing matcher. Found token <$0> while looking for ','.";
  case ErrorType::ParserNoCode:
    return "End of code found while looking for token.";
  case ErrorType::ParserNotAMatcher:
    return "Input value is not a matcher expression.";
  case ErrorType::ParserInvalidToken:
    return "Invalid token <$0> found when looking for a value.";
  case ErrorType::ParserTrailingCode:
    return "Unexpected end of code.";
  case ErrorType::ParserOverloadedType:
    return "Input value has unresolved overloaded type: $0";
  case ErrorType::ParserMalformedChainedExpr:
    return "Period not followed by valid chained call.";
  case ErrorType::ParserChainedExprInvalidArg:
    return "Missing/Invalid argument for the chained call.";
  case ErrorType::ParserChainedExprNoCloseParen:
    return "Missing ')' for the chained call.";
  case ErrorType::ParserChainedExprNoOpenParen:
    return "Missing '(' for the chained call.";
  case ErrorType::ParserFailedToBuildMatcher:
    return "Failed to build matcher: $0.";

  case ErrorType::None:
    return "<N/A>";
  }
  llvm_unreachable("Unknown ErrorType value.");
}

static void formatErrorString(llvm::StringRef formatString,
                              llvm::ArrayRef<std::string> args,
                              llvm::raw_ostream &os) {
  while (!formatString.empty()) {
    std::pair<llvm::StringRef, llvm::StringRef> pieces =
        formatString.split("$");
    os << pieces.first.str();
    if (pieces.second.empty())
      break;

    const char next = pieces.second.front();
    formatString = pieces.second.drop_front();
    if (next >= '0' && next <= '9') {
      const unsigned index = next - '0';
      if (index < args.size()) {
        os << args[index];
      } else {
        os << "<Argument_Not_Provided>";
      }
    }
  }
}

static void maybeAddLineAndColumn(SourceRange range, llvm::raw_ostream &os) {
  if (range.start.line > 0 && range.start.column > 0) {
    os << range.start.line << ":" << range.start.column << ": ";
  }
}

void Diagnostics::printMessage(
    const Diagnostics::ErrorContent::Message &message, const llvm::Twine prefix,
    llvm::raw_ostream &os) const {
  maybeAddLineAndColumn(message.range, os);
  os << prefix;
  formatErrorString(errorTypeToFormatString(message.type), message.args, os);
}

void Diagnostics::printErrorContent(const Diagnostics::ErrorContent &content,
                                    llvm::raw_ostream &os) const {
  if (content.messages.size() == 1) {
    printMessage(content.messages[0], "", os);
  } else {
    for (size_t i = 0, e = content.messages.size(); i != e; ++i) {
      if (i != 0)
        os << "\n";
      printMessage(content.messages[i],
                   "Candidate " + llvm::Twine(i + 1) + ": ", os);
    }
  }
}

void Diagnostics::print(llvm::raw_ostream &os) const {
  for (const ErrorContent &error : errorValues) {
    if (&error != &errorValues.front())
      os << "\n";
    printErrorContent(error, os);
  }
}

} // namespace mlir::query::matcher::internal
