///|
pub type Span = (Int, Int)

///|
pub struct QuadSpan {
  subj : Span
  pred : Span
  obj : Span
  graph : Span?
  line : Int
  subj_type : TermType // 主语类型
  obj_type : TermType // 宾语类型  
} derive(Debug)

///|
pub impl Show for QuadSpan with fn output(self : QuadSpan, logger : &Logger) -> Unit {
  logger.write("QuadSpan")
  logger.write("{ ")
  logger.write("subj: ")
  logger.write(@debug.to_string(self.subj))
  logger.write(", ")
  logger.write("pred: ")
  logger.write(@debug.to_string(self.pred))
  logger.write(", ")
  logger.write("obj: ")
  logger.write(@debug.to_string(self.obj))
  logger.write(", ")
  logger.write("graph: ")
  if self.graph is Some(graph) {
    logger.write(@debug.to_string(graph))
  }
  logger.write(", ")
  logger.write("line: ")
  logger.write(self.line)
  logger.write(", ")
  logger.write("subj_type: ")
  logger.write(@debug.to_string(self.subj_type))
  logger.write(", ")
  logger.write("obj_type: ")
  logger.write(@debug.to_string(self.obj_type))
  logger.write("}")
}

///|
pub(all) enum TermType {
  Unknown
  Iri
  BNode
  Literal
  PrefName
} derive(Debug, Eq)

///|
pub impl Show for TermType with fn output(self : TermType, logger : &Logger) -> Unit {
  match self {
    Iri => logger.write("Iri")
    BNode => logger.write("BNode")
    PrefName => logger.write("PrefName")
    Literal => logger.write("Literal")
    Unknown => logger.write("Unknown")
  }
}

///|
pub struct ParserIter[E] {
  parser : Parser[E]
}

///|
pub fn[E] ParserIter::new(parser : Parser[E]) -> ParserIter[E] {
  { parser, }
}

///|
pub fn[E : ParserEngine] ParserIter::next(
  self : ParserIter[E],
) -> Result[PendingQuad, ParseError]? {
  self.parser.next()
}

///|
pub struct SliceParser[E] {
  inner : ParserIter[E]
  data : ArrayView[Byte]
  lenient : Bool // lenient 模式下跳过验证
}

///|
pub fn[E] SliceParser::new(
  parser : Parser[E],
  data : ArrayView[Byte],
  lenient? : Bool = false,
) -> SliceParser[E] {
  { inner: ParserIter::new(parser), data, lenient }
}

///|
/// 链式调用设置宽松模式
pub fn[E] SliceParser::lenient(self : SliceParser[E]) -> SliceParser[E] {
  { ..self, lenient: true }
}

///|
/// 实现 Iter trait
pub fn[E : ParserEngine] SliceParser::next(
  self : SliceParser[E],
) -> Result[QuadSpan, ParseError]? {
  let result = self.inner.next()
  match result {
    None => None
    Some(Err(e)) => Some(Err(e))
    Some(Ok(pending)) => {
      let validated = self.validate(pending)

      match validated {
        Ok(q) => Some(Ok(q))
        Err(e) => Some(Err(e))
      }
    }
  }
}

///|
/// 解析全部
pub fn[E : ParserEngine] SliceParser::parse_all(
  self : SliceParser[E],
) -> (Array[QuadSpan], Array[ParseError]) {
  let quads : Array[QuadSpan] = []
  let errors = []

  for ;; {
    match self.next() {
      Some(Ok(q)) => quads.push(q)
      Some(Err(e)) => errors.push(e)
      None => break
    }
  }

  (quads, errors)
}

///|
/// 物化 Quad(批量优化)
pub fn materialize_quad(
  quad : QuadSpan,
  data : ArrayView[Byte],
) -> Result[QuadEmit, ParseError] {
  // 提取 span 并切分 data
  let (subj_off, subj_len) = quad.subj
  let (pred_off, pred_len) = quad.pred
  let (obj_off, obj_len) = quad.obj

  // 边界检查
  if subj_off < 0 || subj_off + subj_len > data.length() {
    return Err(ParseError::InvalidToken("Invalid subject span", quad.subj))
  }
  if pred_off < 0 || pred_off + pred_len > data.length() {
    return Err(ParseError::InvalidToken("Invalid predicate span", quad.pred))
  }
  if obj_off < 0 || obj_off + obj_len > data.length() {
    return Err(ParseError::InvalidToken("Invalid object span", quad.obj))
  }

  let subject_view = data[subj_off:subj_off + subj_len]
  let predicate_view = data[pred_off:pred_off + pred_len]
  let object_view = data[obj_off:obj_off + obj_len]

  // 物化
  let subject = match materialize_subject(subject_view, quad.subj_type) {
    Ok(s) => s
    Err(e) => return Err(e)
  }
  let predicate = match materialize_predicate(predicate_view) {
    Ok(p) => p
    Err(e) => return Err(e)
  }
  let object = match materialize_object(object_view, quad.obj_type) {
    Ok(o) => o
    Err(e) => return Err(e)
  }

  // 图名(可选)
  let graph_name = match quad.graph {
    Some((g_off, g_len)) => {
      if g_off < 0 || g_off + g_len > data.length() {
        return Err(
          ParseError::InvalidToken("Invalid graph span", (g_off, g_len)),
        )
      }
      let graph_view = data[g_off:g_off + g_len]
      match materialize_graph_name(Some(graph_view)) {
        Ok(g) => g
        Err(e) => return Err(e)
      }
    }
    None =>
      match materialize_graph_name(None) {
        Ok(g) => g
        Err(e) => return Err(e)
      }
  }

  Ok({ subject, predicate, object, graph_name, line: quad.line })
}

///|
/// 批量物化(优化:减少函数调用开销)
pub fn materialize_all(
  quads : Array[QuadSpan],
  data : ArrayView[Byte],
) -> (Array[QuadEmit], Array[ParseError]) {
  let results = []
  let errors = []

  for quad in quads {
    match materialize_quad(quad, data) {
      Ok(q) => results.push(q)
      Err(e) => errors.push(e)
    }
  }

  (results, errors)
}

///|
fn materialize_subject(
  subject : ArrayView[Byte],
  t : TermType,
) -> Result[Subject, ParseError] {
  match t {
    TermType::Iri => Ok(Subject::Iri(subject))
    TermType::BNode => Ok(Subject::BNode(subject))
    TermType::PrefName =>
      Err(
        ParseError::InvalidErrMessage("N-Quads does not support prefixed names"),
      )
    TermType::Literal =>
      Err(ParseError::InvalidErrMessage("Subject cannot be literal"))
    TermType::Unknown => Err(ParseError::InvalidErrMessage("Invalid subject"))
  }
}

///|
fn materialize_object(
  object : ArrayView[Byte],
  t : TermType,
) -> Result[Object, ParseError] {
  match t {
    TermType::Iri => Ok(Object::Iri(object))
    TermType::BNode => Ok(Object::BNode(object))
    TermType::Literal => Ok(Object::Literal(object))
    TermType::PrefName =>
      Err(
        ParseError::InvalidErrMessage("N-Quads does not support prefixed names"),
      )
    TermType::Unknown => Err(ParseError::InvalidErrMessage("Invalid object"))
  }
}

///|
fn materialize_predicate(
  predicate : ArrayView[Byte],
) -> Result[Predicate, ParseError] {
  // 谓语必须是 IRI,这里只做基本验证
  Ok(predicate)
}

///|
fn materialize_graph_name(
  graph : ArrayView[Byte]?,
) -> Result[GraphName, ParseError] {
  match graph {
    Some(g) => Ok(GraphName::Iri(g))
    None => Ok(GraphName::None)
  }
}

///|
fn[E] SliceParser::validate(
  self : SliceParser[E],
  pending : PendingQuad,
) -> Result[QuadSpan, ParseError] {
  // 结构检查
  let subj = match pending.subj {
    Some(s) => s
    None =>
      return Err(
        ParseError::InvalidToken("Missing subject", pending.compute_span()),
      )
  }
  let pred = match pending.pred {
    Some(p) => p
    None =>
      return Err(
        ParseError::InvalidToken("Missing predicate", pending.compute_span()),
      )
  }
  let obj = match pending.obj {
    Some(o) => o
    None =>
      return Err(
        ParseError::InvalidToken("Missing object", pending.compute_span()),
      )
  }

  // 检测主语和宾语的类型
  let subj_type = detect_term_type(subj, self.data)
  let obj_type = detect_term_type(obj, self.data)

  // 严格模式:验证 IRI 格式
  if !self.lenient {
    // 验证 IRI
    if subj_type == TermType::Iri {
      match validate_iri(self.data, subj) {
        Ok(_) => ()
        Err(e) => return Err(e)
      }
    }
    if obj_type == TermType::Iri {
      match validate_iri(self.data, obj) {
        Ok(_) => ()
        Err(e) => return Err(e)
      }
    }
    // 验证 BlankNode
    if subj_type == TermType::BNode {
      match validate_bnode(self.data, subj) {
        Ok(_) => ()
        Err(e) => return Err(e)
      }
    }
    if obj_type == TermType::BNode {
      match validate_bnode(self.data, obj) {
        Ok(_) => ()
        Err(e) => return Err(e)
      }
    }
  }

  Ok({
    subj,
    pred,
    obj,
    graph: pending.graph,
    line: pending.line,
    subj_type,
    obj_type,
  })
}

///|
/// IRI 验证
pub fn validate_iri(
  data : ArrayView[Byte],
  span : Span,
) -> Result[Span, ParseError] {
  let (offset, length) = span
  let end = offset + length

  // 边界检查
  if offset < 0 || end > data.length() || offset >= end {
    return Err(ParseError::InvalidToken("Invalid span", span))
  }

  // 格式检查:<> 包裹
  if length < 2 || data[offset] != b'<' || data[end - 1] != b'>' {
    return Err(ParseError::InvalidToken("IRI must be wrapped in <>", span))
  }

  let content_start = offset + 1
  let content_end = end - 1
  let content_len = content_end - content_start

  // 非空检查
  if content_len == 0 {
    return Err(ParseError::InvalidToken("IRI cannot be empty", span))
  }

  // http:// 需要 8 个字符
  let c0 = data[content_start]

  let is_http = content_len >= 8 &&
    c0 == b'h' &&
    data[content_start + 1] == b't' &&
    data[content_start + 2] == b't' &&
    data[content_start + 3] == b'p' &&
    data[content_start + 4] == b':' &&
    data[content_start + 5] == b'/' &&
    data[content_start + 6] == b'/'

  let is_https = content_len >= 9 &&
    c0 == b'h' &&
    data[content_start + 1] == b't' &&
    data[content_start + 2] == b't' &&
    data[content_start + 3] == b'p' &&
    data[content_start + 4] == b's' &&
    data[content_start + 5] == b':' &&
    data[content_start + 6] == b'/' &&
    data[content_start + 7] == b'/'

  if !(is_http || is_https) {
    return Err(
      ParseError::InvalidToken("IRI must start with http:// or https://", span),
    )
  }

  // 字符检查
  for i = content_start; i < content_end; i = i + 1 {
    if is_illegal_iri_char(data[i]) {
      return Err(
        ParseError::InvalidToken("IRI contains illegal character", span),
      )
    }
  }

  Ok(span)
}

///|
fn validate_bnode(
  data : ArrayView[Byte],
  span : Span,
) -> Result[Span, ParseError] {
  let (offset, length) = span
  let end = offset + length

  if length < 2 || !(data[offset] == b'_' && data[offset + 1] == b':') {
    return Err(ParseError::InvalidToken("Blank node must start with _:", span))
  }

  let label_start = offset + 2
  if label_start >= end {
    return Err(ParseError::InvalidToken("Blank node label is empty", span))
  }

  if !is_pn_chars_u(data[label_start]) {
    return Err(
      ParseError::InvalidToken(
        "Blank node label must start with letter or underscore", span,
      ),
    )
  }

  let mut last = label_start
  let mut i = label_start + 1
  while i < end && is_pn_chars(data[i]) {
    last = i
    i += 1
  }

  if data[last] == b'.' && last > label_start {
    return Err(ParseError::InvalidToken("Blank node cannot end with '.'", span))
  }

  Ok(span)
}

///|
let first_byte_type : FixedArray[TermType] = {
  let table = FixedArray::make(256, TermType::Unknown)
  table[b'_'.to_int()] = TermType::BNode // _: 开头
  table[b'"'.to_int()] = TermType::Literal
  table[b'\''.to_int()] = TermType::Literal
  table['<'.to_int()] = TermType::Iri // ← 添加
  table
}

///|
fn detect_term_type(span : Span, data : ArrayView[Byte]) -> TermType {
  let (offset, length) = span
  if length == 0 {
    return TermType::Unknown
  }
  let first = data[offset]
  // debug("detect_term_type: first='\{first.to_char()}', length=\{length}")

  let t = first_byte_type[first.to_int()]
  match t {
    TermType::Iri =>
      if length >= 2 && first == b'<' && data[offset + length - 1] == b'>' {
        TermType::Iri
      } else {
        TermType::PrefName
      }
    TermType::BNode =>
      if length >= 2 && data[1] == b':' {
        TermType::BNode
      } else {
        TermType::PrefName
      }
    TermType::Literal => TermType::Literal
    _ =>
      if is_numeric_string(span, data) {
        TermType::Literal
      } else {
        TermType::PrefName
      }
  }
}

///|
/// 检测是否是数字字符串
fn is_numeric_string(span : Span, data : ArrayView[Byte]) -> Bool {
  let (offset, length) = span
  if length == 0 {
    return false
  }
  let first = data[offset]
  if first >= b'0' && first <= b'9' {
    return true
  }
  if first == b'-' || first == b'+' {
    return length > 1 && data[offset + 1] >= b'0' && data[offset + 1] <= b'9'
  }
  false
}