///|
pub struct Parser[E] {
  lexer : Lexerc
  engine : E
  pending : PendingQuad
  errors : Array[ParseError]
  data : ArrayView[Byte]
  // line : Int // 当前行号
}

///|
pub fn[E : ParserEngine] Parser::new(
  lexer : Lexerc,
  engine : E,
  data : ArrayView[Byte],
  // line : Int,
) -> Parser[E] {
  { lexer, engine, pending: engine.create_pending(), errors: [], data }
}

///|
pub fn[E : ParserEngine] Parser::from_bytes(
  data : FixedArray[Byte],
  engine : E,
) -> Parser[E] {
  Parser::new(Lexerc::new(data), engine, data)
}

///|
pub fn nquads_parser(data : FixedArray[Byte]) -> Parser[NQuadsEngine] {
  let engine = NQuadsEngine::new()
  Parser::from_bytes(data, engine)
}

///|
pub fn[E] Parser::data(self : Parser[E]) -> ArrayView[Byte] {
  self.data
}

///|
fn is_eof_token(token : Token) -> Bool {
  match token {
    Token::EOF(_) => true
    _ => false
  }
}

///|
/// 解析步骤结果
pub(all) enum StepResult {
  Continue // 继续解析下一个 token
  Emit // 触发输出(emit pending)
  SkipLine // 跳过当前行(遇到错误时)
  Error(ParseError) // 遇到错误
}

///|
pub trait ParserEngine {
  ///| 获取错误恢复状态
  fn error_recovery_state(Self) -> Self

  ///| 创建初始的 PendingQuad
  /// 返回 None 表示当前不需要开始一个新的 Quad(如遇到空行或注释)
  fn create_pending(Self) -> PendingQuad

  ///| 消费一个 token,返回解析结果
  fn step(Self, pending : PendingQuad, token : Token) -> StepResult

  ///| 检查 pending 是否完整(可用于最终验证)
  fn is_complete(Self, pending : PendingQuad) -> Bool

  ///| 处理结束
  /// 当输入结束时调用,用于处理最后一个未完成的 pending
  fn recognize_end(Self, pending : PendingQuad, results : Array[Span]) -> Unit

  ///| 获取引擎特定的 LexerOptions(可选)
  // fn lexer_options() -> RdfMode
}

///|
pub fn[E] Parser::get_errors(self : Parser[E]) -> Array[ParseError] {
  self.errors
}

///|
pub fn[E : ParserEngine] Parser::next(
  self : Parser[E],
) -> Result[PendingQuad, ParseError]? {
  self.pending.reset()

  for ;; {
    match self.lexer.next() {
      None => {
        if self.pending.state != ExpectSubject &&
          (
            self.pending.subj is Some(_) ||
            self.pending.pred is Some(_) ||
            self.pending.obj is Some(_)
          ) {
          self.errors.push(
            ParseError::InvalidToken(
              "Incomplete triple at end of input",
              self.pending.compute_span(),
            ),
          )
        }
        return None
      }
      Some(token) =>
        if is_eof_token(token) {
          if self.pending.state != ExpectSubject &&
            (
              self.pending.subj is Some(_) ||
              self.pending.pred is Some(_) ||
              self.pending.obj is Some(_)
            ) {
            self.errors.push(
              ParseError::InvalidToken(
                "Incomplete triple at end of input",
                self.pending.compute_span(),
              ),
            )
          }
          return None
        } else {
          match self.engine.step(self.pending, token) {
            Continue => continue
            Emit => {
              let result = self.pending
              return Some(Ok(result))
            }
            SkipLine => {
              self.pending.reset()
              continue
            }
            Error(err) => {
              self.errors.push(err)
              self.pending.reset()
              let error_result = Some(Err(err))
              // 返回错误后,调用者决定是否继续
              return error_result
              // return Some(Err(err))
            }
          }
        }
    }
  }
}