///|
pub(all) struct NQuadsRecognizer {
  current_state : NQuadsState
  stack : Array[NQuadsState]
  mut emit_quad : Bool
  temp_literal : String?
  lenient : Bool
  debug_logger : &DebugLogger
  mut last_range : Range
  errors : Array[RuleRecognizerError]
}

///|
pub(all) struct NQuadsRecognizerContext {
  with_graph_name : Bool
  lexer_options : LexerOptions
}

///|
pub(all) struct DataWorld {
  mut subjects : Array[NamedOrBlankNodeRef]
  mut predicates : Array[NamedNodeRef]
  mut objects : Array[TermRef]
  mut temp_literal : String?
  mut finalize_literal : LiteralKind?
  mut graph_name : GraphNameRef?
} derive(Debug, Eq, Hash)

// impl DataWorld for DataWorld with fn default(self) -> Unit {
// ...
// }

///|
pub(all) enum DataAction {
  NoOp // ✅ 新增
  AddSubject(NamedOrBlankNodeRef)
  AddPredicate(NamedNodeRef)
  AddObject(TermRef)
  SetTempLiteral(String)
  SetGraphName(GraphNameRef)
  EmitQuad
  EmitQuadWithLiteral(LiteralKind)
  EmitQuadWithTempLiteral(NamedNodeRef)
  PushStack(NQuadsState)
  ClearAccumulator
  FinalizeLiteral(LiteralKind)
  FinalizeQuotedTriple
}

///|
impl Show for DataAction with fn output(self, logger : &Logger) -> Unit {
  match self {
    DataAction::NoOp => logger.write("NoOp")
    DataAction::AddSubject(subject) => {
      logger.write("AddSubject(")
      logger.write(subject)
      logger.write(")")
    }
    DataAction::AddPredicate(predicate) => {
      logger.write("AddPredicate(")
      logger.write(predicate)
      logger.write(")")
    }
    DataAction::AddObject(object) => {
      logger.write("AddObject(")
      logger.write(object)
      logger.write(")")
    }
    DataAction::SetTempLiteral(temp_literal) => {
      logger.write("SetTempLiteral(")
      logger.write(temp_literal)
      logger.write(")")
    }
    DataAction::SetGraphName(graph_name) => {
      logger.write("SetGraphName(")
      logger.write(graph_name)
      logger.write(")")
    }
    DataAction::EmitQuad => logger.write("EmitQuad")
    DataAction::EmitQuadWithLiteral(finalize_literal) => {
      logger.write("EmitQuadWithLiteral(")
      logger.write(finalize_literal)
      logger.write(")")
    }
    DataAction::EmitQuadWithTempLiteral(finalize_literal) => {
      logger.write("EmitQuadWithTempLiteral(")
      logger.write(finalize_literal)
      logger.write(")")
    }
    DataAction::PushStack(state) => {
      logger.write("PushStack(")
      logger.write(state)
      logger.write(")")
    }
    DataAction::ClearAccumulator => logger.write("ClearAccumulator")
    DataAction::FinalizeLiteral(finalize_literal) => {
      logger.write("FinalizeLiteral(")
      logger.write(finalize_literal)
      logger.write(")")
    }
    DataAction::FinalizeQuotedTriple => logger.write("FinalizeQuotedTriple")
  }
}

///|
pub fn DataWorld::DataWorld(
  subjects : Array[NamedOrBlankNodeRef],
  predicates : Array[NamedNodeRef],
  objects : Array[TermRef],
  temp_literal : String?,
  finalize_literal : LiteralKind?,
  graph_name : GraphNameRef?,
) -> DataWorld {
  DataWorld::{
    subjects,
    predicates,
    objects,
    temp_literal,
    finalize_literal,
    graph_name,
  }
}

///|
pub fn DataWorld::default() -> DataWorld {
  DataWorld::DataWorld(
    Array::new(),
    Array::new(),
    Array::new(),
    None,
    None,
    None,
  )
}

///|
pub(all) enum LiteralKind {
  Simple
  Lang(LanguageTag, BaseDirection)
  Typed(String, NamedNodeRef)
} derive(Debug, Eq, Hash)

///|
pub impl Show for LiteralKind with fn output(self, logger : &Logger) -> Unit {
  match self {
    LiteralKind::Simple => logger.write("Simple")
    LiteralKind::Lang(lang, dir) => {
      logger.write("Lang(")
      logger.write(lang)
      logger.write(", ")
      logger.write(dir)
      logger.write(")")
    }
    LiteralKind::Typed(data_type, iri) => {
      logger.write("Typed(")
      logger.write(data_type)
      logger.write(", ")
      logger.write(iri)
      logger.write(")")
    }
  }
}

///|
pub(all) enum NQuadsState {
  // ==========================================
  // 1. 文档级 (Document Level)
  // ==========================================

  /// 初始状态。
  /// 期待遇到四元组/三元组的第一个 token(主语),或注释/空白。
  /// N-Quads 没有 @prefix/@base 等指令,直接开始解析三元组。
  Start

  // ==========================================
  // 2. 四元组核心级 (Quad Core)
  // ==========================================

  /// 期待读取主语(Subject)。
  /// 主语可以是 IRI 或 Blank Node。
  ExpectSubject
  /// 已读取主语,期待读取谓语(Predicate)。
  /// 谓语必须是 IRI。
  ExpectPredicate
  /// 已读取谓语,期待读取宾语(Object)。
  /// 宾语可以是 IRI、Blank Node 或 Literal。
  ExpectObject
  /// 已读取宾语,期待判断四元组是否包含图名。
  /// - 遇到 `.`:三元组结束,无图名(默认图)
  /// - 遇到 IRI 或 Blank Node:进入图名解析
  ExpectDotOrGraphName
  /// 已判定存在图名,期待读取图名(Graph IRI 或 Blank Node)。
  /// 图名用于标识该三元组所属的命名图。
  ExpectGraphName
  /// 已读取图名(或宾语后直接为 `.`),期待句点 `.` 结束当前四元组。
  ExpectDot

  // ==========================================
  // 3. 字面量后缀级 (Literal Suffix)
  // ==========================================

  /// 期待字面量(Literal)的后缀。
  /// 处理字符串后面的语言标签(如 @en)或数据类型标记(^^)。
  /// N-Quads 中字面量语法与 Turtle 相同。
  ExpectLiteralSuffix
  /// 遇到 `^^` 后,期待读取具体的数据类型 IRI。
  ExpectDatatype
  ExpectLineJump
} derive(Debug, Eq, Hash)

///|
pub(all) enum NQuadsAction {
  // 主体积木操作
  PushSubject(NamedOrBlankNodeRef)
  PushPredicate(NamedNodeRef)
  PushObject(TermRef)

  // 字面量处理
  SetTempLiteral(String)
  FinalizeSimpleLiteral
  FinalizeLangLiteral(String, BaseDirection)

  // 图名处理
  SetGraphName(NamedOrBlankNodeRef)
  EmitQuad
  EmitQuadWithGraphName

  // 引号三元组 (<< >>)
  PushStack(NQuadsState)
  PopStack
  FinalizeQuotedTriple

  // 错误恢复
  SetError(RuleRecognizerError)
  ClearAccumulator
}

///|
impl StateWrapper for NQuadsState with fn as_state_enum(self : NQuadsState) -> RdfState {
  RdfState::NQuadsState(self)
}

///|
impl Show for NQuadsState with fn output(self, logger : &Logger) -> Unit {
  match self {
    NQuadsState::Start => logger.write("Start")
    NQuadsState::ExpectSubject => logger.write("ExpectSubject")
    NQuadsState::ExpectPredicate => logger.write("ExpectPredicate")
    NQuadsState::ExpectObject => logger.write("ExpectObject")
    NQuadsState::ExpectDotOrGraphName => logger.write("ExpectDotOrGraphName")
    NQuadsState::ExpectGraphName => logger.write("ExpectGraphName")
    NQuadsState::ExpectDot => logger.write("ExpectDot")
    NQuadsState::ExpectLiteralSuffix => logger.write("ExpectLiteralSuffix")
    NQuadsState::ExpectDatatype => logger.write("ExpectDatatype")
    NQuadsState::ExpectLineJump => logger.write("ExpectLineJump")
  }
}

///|
pub impl RuleRecognizer for NQuadsRecognizer with fn error_recovery_state(
  self : NQuadsRecognizer,
) -> NQuadsRecognizer {
  // self.stack.clear()
  // self.stack.push(NQuadsState::RecoverToLineJump)
  // self.subjects.clear()
  // self.predicates.clear()
  // self.objects.clear()
  self
}

///|
// pub impl RuleRecognizer for NQuadsRecognizer with fn[DL : DebugLogger] debug_logger(
//   self : NQuadsRecognizer,
//   debug_logger : DL,
// ) {
//   self.debug_logger = debug_logger
// }

///|
pub impl RuleRecognizer for NQuadsRecognizer with fn recognize_end(
  _self : NQuadsRecognizer,
  _context : RdfContext,
  _results : Array[RdfOut],
) -> Unit {
  ()
}

///|
pub impl RuleRecognizer for NQuadsRecognizer with fn lexer_options(
  context : RdfContext,
) -> LexerOptions? {
  match context {
    RdfContext::NQuadsRecognizerContext(ctx) => Some(ctx.lexer_options)
  }
}

///|
pub fn NQuadsRecognizer::new_parser(
  data : Array[Byte],
  with_graph_name : Bool,
  lenient : Bool,
  debug_logger? : &DebugLogger = make_mute_logger(),
) -> Parser[RdfLexer, NQuadsRecognizer] {
  let initial_context = NQuadsRecognizerContext::{
    with_graph_name,
    lexer_options: { base_iri: None },
  }
  let lexer = Lexer::Lexer(
    RdfLexer::RdfLexer(RdfLexerMode::NTriples, lenient, []),
    data,
    true,
    MIN_BUFFER_SIZE,
    MAX_BUFFER_SIZE,
    Some(b"#"),
    0,
    0,
  )

  let machine = NQuadsRecognizer::{
    current_state: NQuadsState::Start,
    stack: [NQuadsState::Start],
    emit_quad: false,
    // finalize_literal: None,
    // last_output: None,
    temp_literal: None,
    lenient,
    debug_logger, // 修复:包装为 Option 类型
    last_range: Range::default(),
    errors: [],
  }
  let context = RdfContext::NQuadsRecognizerContext(initial_context)
  let generic_machine = GenericStateMachine::{
    machine,
    context,
    outputs: [],
    data_world: DataWorld::default(),
    debug_logger,
    lexer_errors: [],
  }
  Parser::{ lexer, engine: generic_machine, context, errors: [] }
  // Parser::Parser(lexer, machine, context)
}