import { Directives as m } from "./accelbyte-widgets648.mjs";
import { Document as f } from "./accelbyte-widgets709.mjs";
import { YAMLWarning as l, YAMLParseError as h } from "./accelbyte-widgets710.mjs";
import { isCollection as p, isPair as u } from "./accelbyte-widgets711.mjs";
import { composeDoc as g } from "./accelbyte-widgets712.mjs";
import { resolveEnd as E } from "./accelbyte-widgets713.mjs";
function c(o) {
  if (typeof o == "number")
    return [o, o + 1];
  if (Array.isArray(o))
    return o.length === 2 ? o : [o[0], o[1]];
  const { offset: e, source: s } = o;
  return [e, e + (typeof s == "string" ? s.length : 1)];
}
function d(o) {
  var i;
  let e = "", s = !1, t = !1;
  for (let r = 0; r < o.length; ++r) {
    const n = o[r];
    switch (n[0]) {
      case "#":
        e += (e === "" ? "" : t ? `

` : `
`) + (n.substring(1) || " "), s = !0, t = !1;
        break;
      case "%":
        ((i = o[r + 1]) == null ? void 0 : i[0]) !== "#" && (r += 1), s = !1;
        break;
      default:
        s || (t = !0), s = !1;
    }
  }
  return { comment: e, afterEmptyLine: t };
}
class A {
  constructor(e = {}) {
    this.doc = null, this.atDirectives = !1, this.prelude = [], this.errors = [], this.warnings = [], this.onError = (s, t, i, r) => {
      const n = c(s);
      r ? this.warnings.push(new l(n, t, i)) : this.errors.push(new h(n, t, i));
    }, this.directives = new m({ version: e.version || "1.2" }), this.options = e;
  }
  decorate(e, s) {
    const { comment: t, afterEmptyLine: i } = d(this.prelude);
    if (t) {
      const r = e.contents;
      if (s)
        e.comment = e.comment ? `${e.comment}
${t}` : t;
      else if (i || e.directives.docStart || !r)
        e.commentBefore = t;
      else if (p(r) && !r.flow && r.items.length > 0) {
        let n = r.items[0];
        u(n) && (n = n.key);
        const a = n.commentBefore;
        n.commentBefore = a ? `${t}
${a}` : t;
      } else {
        const n = r.commentBefore;
        r.commentBefore = n ? `${t}
${n}` : t;
      }
    }
    s ? (Array.prototype.push.apply(e.errors, this.errors), Array.prototype.push.apply(e.warnings, this.warnings)) : (e.errors = this.errors, e.warnings = this.warnings), this.prelude = [], this.errors = [], this.warnings = [];
  }
  streamInfo() {
    return {
      comment: d(this.prelude).comment,
      directives: this.directives,
      errors: this.errors,
      warnings: this.warnings
    };
  }
  *compose(e, s = !1, t = -1) {
    for (const i of e)
      yield* this.next(i);
    yield* this.end(s, t);
  }
  *next(e) {
    switch (e.type) {
      case "directive":
        this.directives.add(e.source, (s, t, i) => {
          const r = c(e);
          r[0] += s, this.onError(r, "BAD_DIRECTIVE", t, i);
        }), this.prelude.push(e.source), this.atDirectives = !0;
        break;
      case "document": {
        const s = g(this.options, this.directives, e, this.onError);
        this.atDirectives && !s.directives.docStart && this.onError(e, "MISSING_CHAR", "Missing directives-end/doc-start indicator line"), this.decorate(s, !1), this.doc && (yield this.doc), this.doc = s, this.atDirectives = !1;
        break;
      }
      case "byte-order-mark":
      case "space":
        break;
      case "comment":
      case "newline":
        this.prelude.push(e.source);
        break;
      case "error": {
        const s = e.source ? `${e.message}: ${JSON.stringify(e.source)}` : e.message, t = new h(c(e), "UNEXPECTED_TOKEN", s);
        this.atDirectives || !this.doc ? this.errors.push(t) : this.doc.errors.push(t);
        break;
      }
      case "doc-end": {
        if (!this.doc) {
          const t = "Unexpected doc-end without preceding document";
          this.errors.push(new h(c(e), "UNEXPECTED_TOKEN", t));
          break;
        }
        this.doc.directives.docEnd = !0;
        const s = E(e.end, e.offset + e.source.length, this.doc.options.strict, this.onError);
        if (this.decorate(this.doc, !0), s.comment) {
          const t = this.doc.comment;
          this.doc.comment = t ? `${t}
${s.comment}` : s.comment;
        }
        this.doc.range[2] = s.offset;
        break;
      }
      default:
        this.errors.push(new h(c(e), "UNEXPECTED_TOKEN", `Unsupported token ${e.type}`));
    }
  }
  *end(e = !1, s = -1) {
    if (this.doc)
      this.decorate(this.doc, !0), yield this.doc, this.doc = null;
    else if (e) {
      const t = Object.assign({ _directives: this.directives }, this.options), i = new f(void 0, t);
      this.atDirectives && this.onError(s, "MISSING_CHAR", "Missing directives-end indicator line"), i.range = [0, s, s], this.decorate(i, !1), yield i;
    }
  }
}
export {
  A as Composer
};
