/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
 * Use of this file is governed by the BSD 3-clause license that
 * can be found in the LICENSE.txt file in the project root.
 */

#include <string.h>

#include "Exceptions.h"
#include "misc/Interval.h"
#include "IntStream.h"

#include "support/StringUtils.h"
#include "support/CPPUtils.h"

#include "ANTLRInputStream.h"

using namespace antlr4;
using namespace antlrcpp;

using misc::Interval;

ANTLRInputStream::ANTLRInputStream() {
  InitializeInstanceFields();
}

#if __cplusplus >= 201703L
ANTLRInputStream::ANTLRInputStream(const std::string_view &input): ANTLRInputStream() {
  load(input.data(), input.length());
}
#endif

ANTLRInputStream::ANTLRInputStream(const std::string &input): ANTLRInputStream() {
  load(input.data(), input.size());
}

ANTLRInputStream::ANTLRInputStream(const char *data, size_t length) {
  load(data, length);
}

ANTLRInputStream::ANTLRInputStream(std::istream &stream): ANTLRInputStream() {
  load(stream);
}

void ANTLRInputStream::load(const std::string &input) {
  load(input.data(), input.size());
}

void ANTLRInputStream::load(const char *data, size_t length) {
  // Remove the UTF-8 BOM if present.
  const char *bom = "\xef\xbb\xbf";
  if (length >= 3 && strncmp(data, bom, 3) == 0)
    _data = antlrcpp::utf8_to_utf32(data + 3, data + length);
  else
    _data = antlrcpp::utf8_to_utf32(data, data + length);
  p = 0;
}

void ANTLRInputStream::load(std::istream &stream) {
  if (!stream.good() || stream.eof()) // No fail, bad or EOF.
    return;

  _data.clear();

  std::string s((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
  load(s.data(), s.length());
}

void ANTLRInputStream::reset() {
  p = 0;
}

void ANTLRInputStream::consume() {
  if (p >= _data.size()) {
    assert(LA(1) == IntStream::EOF);
    throw IllegalStateException("cannot consume EOF");
  }

  if (p < _data.size()) {
    p++;
  }
}

size_t ANTLRInputStream::LA(ssize_t i) {
  if (i == 0) {
    return 0; // undefined
  }

  ssize_t position = static_cast<ssize_t>(p);
  if (i < 0) {
    i++; // e.g., translate LA(-1) to use offset i=0; then _data[p+0-1]
    if ((position + i - 1) < 0) {
      return IntStream::EOF; // invalid; no char before first char
    }
  }

  if ((position + i - 1) >= static_cast<ssize_t>(_data.size())) {
    return IntStream::EOF;
  }

  return _data[static_cast<size_t>((position + i - 1))];
}

size_t ANTLRInputStream::LT(ssize_t i) {
  return LA(i);
}

size_t ANTLRInputStream::index() {
  return p;
}

size_t ANTLRInputStream::size() {
  return _data.size();
}

// Mark/release do nothing. We have entire buffer.
ssize_t ANTLRInputStream::mark() {
  return -1;
}

void ANTLRInputStream::release(ssize_t /* marker */) {
}

void ANTLRInputStream::seek(size_t index) {
  if (index <= p) {
    p = index; // just jump; don't update stream state (line, ...)
    return;
  }
  // seek forward, consume until p hits index or n (whichever comes first)
  index = std::min(index, _data.size());
  while (p < index) {
    consume();
  }
}

std::string ANTLRInputStream::getText(const Interval &interval) {
  if (interval.a < 0 || interval.b < 0) {
    return "";
  }

  size_t start = static_cast<size_t>(interval.a);
  size_t stop = static_cast<size_t>(interval.b);


  if (stop >= _data.size()) {
    stop = _data.size() - 1;
  }

  size_t count = stop - start + 1;
  if (start >= _data.size()) {
    return "";
  }

  return antlrcpp::utf32_to_utf8(_data.substr(start, count));
}

std::string ANTLRInputStream::getSourceName() const {
  if (name.empty()) {
    return IntStream::UNKNOWN_SOURCE_NAME;
  }
  return name;
}

std::string ANTLRInputStream::toString() const {
  return antlrcpp::utf32_to_utf8(_data);
}

void ANTLRInputStream::InitializeInstanceFields() {
  p = 0;
}
