/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmExprParserHelper.h"

#include <iostream>
#include <sstream>
#include <stdexcept>
#include <utility>

#include "cmExprLexer.h"
#include "cmStringAlgorithms.h"

int cmExpr_yyparse(yyscan_t yyscanner);
//
cmExprParserHelper::cmExprParserHelper()
{
  this->FileLine = -1;
  this->FileName = nullptr;
  this->Result = 0;
}

cmExprParserHelper::~cmExprParserHelper() = default;

int cmExprParserHelper::ParseString(const char* str, int verb)
{
  if (!str) {
    return 0;
  }
  // printf("Do some parsing: %s\n", str);

  this->Verbose = verb;
  this->InputBuffer = str;
  this->InputBufferPos = 0;
  this->CurrentLine = 0;

  this->Result = 0;

  yyscan_t yyscanner;
  cmExpr_yylex_init(&yyscanner);
  cmExpr_yyset_extra(this, yyscanner);

  try {
    int res = cmExpr_yyparse(yyscanner);
    if (res != 0) {
      std::string e = cmStrCat("cannot parse the expression: \"", InputBuffer,
                               "\": ", ErrorString, '.');
      this->SetError(std::move(e));
    }
  } catch (std::runtime_error const& fail) {
    std::string e = cmStrCat("cannot evaluate the expression: \"", InputBuffer,
                             "\": ", fail.what(), '.');
    this->SetError(std::move(e));
  } catch (std::out_of_range const&) {
    std::string e = "cannot evaluate the expression: \"" + InputBuffer +
      "\": a numeric value is out of range.";
    this->SetError(std::move(e));
  } catch (...) {
    std::string e = "cannot parse the expression: \"" + InputBuffer + "\".";
    this->SetError(std::move(e));
  }
  cmExpr_yylex_destroy(yyscanner);
  if (!this->ErrorString.empty()) {
    return 0;
  }

  if (Verbose) {
    std::cerr << "Expanding [" << str << "] produced: [" << this->Result << "]"
              << std::endl;
  }
  return 1;
}

int cmExprParserHelper::LexInput(char* buf, int maxlen)
{
  // std::cout << "JPLexInput ";
  // std::cout.write(buf, maxlen);
  // std::cout << std::endl;
  if (maxlen < 1) {
    return 0;
  }
  if (this->InputBufferPos < this->InputBuffer.size()) {
    buf[0] = this->InputBuffer[this->InputBufferPos++];
    if (buf[0] == '\n') {
      this->CurrentLine++;
    }
    return (1);
  }
  buf[0] = '\n';
  return (0);
}

void cmExprParserHelper::Error(const char* str)
{
  unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
  std::ostringstream ostr;
  ostr << str << " (" << pos << ")";
  this->ErrorString = ostr.str();
}

void cmExprParserHelper::UnexpectedChar(char c)
{
  unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
  std::ostringstream ostr;
  ostr << "Unexpected character in expression at position " << pos << ": " << c
       << "\n";
  this->WarningString += ostr.str();
}

void cmExprParserHelper::SetResult(KWIML_INT_int64_t value)
{
  this->Result = value;
}

void cmExprParserHelper::SetError(std::string errorString)
{
  this->ErrorString = std::move(errorString);
}
