#include <cstdio>
#include <sstream>

#include "directives.h"  // IWYU pragma: keep
#include "scanner.h"     // IWYU pragma: keep
#include "singledocparser.h"
#include "token.h"
#include "yaml-cpp/exceptions.h"  // IWYU pragma: keep
#include "yaml-cpp/parser.h"

namespace YAML {
class EventHandler;

Parser::Parser() : m_pScanner{}, m_pDirectives{} {}

Parser::Parser(std::istream& in) : Parser() { Load(in); }

Parser::~Parser() = default;

Parser::operator bool() const { return m_pScanner && !m_pScanner->empty(); }

void Parser::Load(std::istream& in) {
  m_pScanner.reset(new Scanner(in));
  m_pDirectives.reset(new Directives);
}

bool Parser::HandleNextDocument(EventHandler& eventHandler) {
  if (!m_pScanner)
    return false;

  ParseDirectives();
  if (m_pScanner->empty()) {
    return false;
  }

  SingleDocParser sdp(*m_pScanner, *m_pDirectives);
  sdp.HandleDocument(eventHandler);
  return true;
}

void Parser::ParseDirectives() {
  bool readDirective = false;

  while (!m_pScanner->empty()) {
    Token& token = m_pScanner->peek();
    if (token.type != Token::DIRECTIVE) {
      break;
    }

    // we keep the directives from the last document if none are specified;
    // but if any directives are specific, then we reset them
    if (!readDirective) {
      m_pDirectives.reset(new Directives);
    }

    readDirective = true;
    HandleDirective(token);
    m_pScanner->pop();
  }
}

void Parser::HandleDirective(const Token& token) {
  if (token.value == "YAML") {
    HandleYamlDirective(token);
  } else if (token.value == "TAG") {
    HandleTagDirective(token);
  }
}

void Parser::HandleYamlDirective(const Token& token) {
  if (token.params.size() != 1) {
    throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
  }

  if (!m_pDirectives->version.isDefault) {
    throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
  }

  std::stringstream str(token.params[0]);
  str >> m_pDirectives->version.major;
  str.get();
  str >> m_pDirectives->version.minor;
  if (!str || str.peek() != EOF) {
    throw ParserException(
        token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
  }

  if (m_pDirectives->version.major > 1) {
    throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
  }

  m_pDirectives->version.isDefault = false;
  // TODO: warning on major == 1, minor > 2?
}

void Parser::HandleTagDirective(const Token& token) {
  if (token.params.size() != 2)
    throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);

  const std::string& handle = token.params[0];
  const std::string& prefix = token.params[1];
  if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) {
    throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
  }

  m_pDirectives->tags[handle] = prefix;
}

void Parser::PrintTokens(std::ostream& out) {
  if (!m_pScanner) {
    return;
  }

  while (!m_pScanner->empty()) {
    out << m_pScanner->peek() << "\n";
    m_pScanner->pop();
  }
}
}  // namespace YAML
