"use client";
import { isSurrogatePair as l, getSurrogatePairCodePoint as f, CODE_POINTS as e, isSurrogate as p, isControlCodePoint as u, isUndefinedCodePoint as d } from "../common/unicode.js";
import { ERR as h } from "../common/error-codes.js";
const c = 65536;
class g {
  constructor(t) {
    this.handler = t, this.html = "", this.pos = -1, this.lastGapPos = -2, this.gapStack = [], this.skipNextNewLine = !1, this.lastChunkWritten = !1, this.endOfChunkHit = !1, this.bufferWaterline = c, this.isEol = !1, this.lineStartPos = 0, this.droppedBufferSize = 0, this.line = 1, this.lastErrOffset = -1;
  }
  /** The column on the current line. If we just saw a gap (eg. a surrogate pair), return the index before. */
  get col() {
    return this.pos - this.lineStartPos + +(this.lastGapPos !== this.pos);
  }
  get offset() {
    return this.droppedBufferSize + this.pos;
  }
  getError(t, s) {
    const { line: i, col: r, offset: a } = this, o = r + s, n = a + s;
    return {
      code: t,
      startLine: i,
      endLine: i,
      startCol: o,
      endCol: o,
      startOffset: n,
      endOffset: n
    };
  }
  _err(t) {
    this.handler.onParseError && this.lastErrOffset !== this.offset && (this.lastErrOffset = this.offset, this.handler.onParseError(this.getError(t, 0)));
  }
  _addGap() {
    this.gapStack.push(this.lastGapPos), this.lastGapPos = this.pos;
  }
  _processSurrogate(t) {
    if (this.pos !== this.html.length - 1) {
      const s = this.html.charCodeAt(this.pos + 1);
      if (l(s))
        return this.pos++, this._addGap(), f(t, s);
    } else if (!this.lastChunkWritten)
      return this.endOfChunkHit = !0, e.EOF;
    return this._err(h.surrogateInInputStream), t;
  }
  willDropParsedChunk() {
    return this.pos > this.bufferWaterline;
  }
  dropParsedChunk() {
    this.willDropParsedChunk() && (this.html = this.html.substring(this.pos), this.lineStartPos -= this.pos, this.droppedBufferSize += this.pos, this.pos = 0, this.lastGapPos = -2, this.gapStack.length = 0);
  }
  write(t, s) {
    this.html.length > 0 ? this.html += t : this.html = t, this.endOfChunkHit = !1, this.lastChunkWritten = s;
  }
  insertHtmlAtCurrentPos(t) {
    this.html = this.html.substring(0, this.pos + 1) + t + this.html.substring(this.pos + 1), this.endOfChunkHit = !1;
  }
  startsWith(t, s) {
    if (this.pos + t.length > this.html.length)
      return this.endOfChunkHit = !this.lastChunkWritten, !1;
    if (s)
      return this.html.startsWith(t, this.pos);
    for (let i = 0; i < t.length; i++)
      if ((this.html.charCodeAt(this.pos + i) | 32) !== t.charCodeAt(i))
        return !1;
    return !0;
  }
  peek(t) {
    const s = this.pos + t;
    if (s >= this.html.length)
      return this.endOfChunkHit = !this.lastChunkWritten, e.EOF;
    const i = this.html.charCodeAt(s);
    return i === e.CARRIAGE_RETURN ? e.LINE_FEED : i;
  }
  advance() {
    if (this.pos++, this.isEol && (this.isEol = !1, this.line++, this.lineStartPos = this.pos), this.pos >= this.html.length)
      return this.endOfChunkHit = !this.lastChunkWritten, e.EOF;
    let t = this.html.charCodeAt(this.pos);
    return t === e.CARRIAGE_RETURN ? (this.isEol = !0, this.skipNextNewLine = !0, e.LINE_FEED) : t === e.LINE_FEED && (this.isEol = !0, this.skipNextNewLine) ? (this.line--, this.skipNextNewLine = !1, this._addGap(), this.advance()) : (this.skipNextNewLine = !1, p(t) && (t = this._processSurrogate(t)), this.handler.onParseError === null || t > 31 && t < 127 || t === e.LINE_FEED || t === e.CARRIAGE_RETURN || t > 159 && t < 64976 || this._checkForProblematicCharacters(t), t);
  }
  _checkForProblematicCharacters(t) {
    u(t) ? this._err(h.controlCharacterInInputStream) : d(t) && this._err(h.noncharacterInInputStream);
  }
  retreat(t) {
    for (this.pos -= t; this.pos < this.lastGapPos; )
      this.lastGapPos = this.gapStack.pop(), this.pos--;
    this.isEol = !1;
  }
}
export {
  g as Preprocessor
};
