///|
const CHUNK_SIZE : Int = 64 * 1024

///|
pub fn get_ntriples_slice_chunks(
  bytes : BytesView,
  n_chunks : Int,
) -> Array[(Int, Int)] {
  if n_chunks <= 0 {
    return [(0, bytes.length())]
  }

  let total_len = bytes.length()
  if total_len == 0 {
    return []
  }

  // 收集所有换行符的位置(换行符之后的位置)
  let line_ends = []
  let mut pos = 0
  while memchr(b'\n', bytes[pos:]) is Some(p) {
    pos += p + 1
    line_ends.push(pos)
  }

  // 如果没有换行符,整个文件作为一个块
  if line_ends.length() == 0 {
    return [(0, total_len)]
  }

  // 按换行符位置分割成 N 块
  let total_lines = line_ends.length()
  let lines_per_chunk = (total_lines / n_chunks).max(1)
  let mut last_pos = 0
  let offsets = []

  for i in 0..= total_len {
      break
    }
  }

  // 如果还有剩余内容(通常是最后一行的换行符导致),添加到最后一个块
  if last_pos < total_len {
    // 合并到最后一个块
    match offsets.pop() {
      Some((start, _)) => offsets.push((start, total_len))
      None => offsets.push((0, total_len)) // 理论上不会发生,但处理了 None 情况
    }
  }

  offsets
}

///|
/// 在指定范围内搜索换行符,返回换行符的绝对位置
pub fn find_newline_in_range(bytes : BytesView, start : Int, end : Int) -> Int? {
  for i in start.. Result[Array[(Int64, Int64)], String] {
  let mut last_pos : Int64 = 0
  let chunk_size = file_size / n_chunks.to_int64()

  let offsets = Array::new(capacity=n_chunks)

  // 用于读取的缓冲区
  let buffer : FixedArray[Byte] = FixedArray::make(CHUNK_SIZE, 0)

  for _ in 0..= file_size {
      break
    }

    let mut end_pos_opt : Int64? = None
    let mut current_read_pos : Int64 = search_pos

    // 从 search_pos 开始向后扫描,寻找换行符
    while current_read_pos < file_size {
      // 计算本次读取的长度,不超过缓冲区大小,也不超过文件末尾
      let remaining = file_size - current_read_pos
      let read_len = if remaining > 4096 { 4096 } else { remaining.to_int() }

      // 使用 read_at 从 current_read_pos 读取数据
      // 注意:read_at 返回实际读取的字节数
      let bytes_read = file.read_at(
        buffer,
        position=current_read_pos,
        len=read_len,
      )

      if bytes_read == 0 {
        break
      }

      // 在 buffer 的前 bytes_read 个字节中查找 '\n'
      let view = buffer[0:bytes_read]
      match array_view_memchr(b'\n', view) {
        Some(pos_in_buffer) => {
          // 找到换行符
          end_pos_opt = Some(current_read_pos + pos_in_buffer.to_int64() + 1)
          break
        }
        None =>
          // 未找到,移动读取位置到下一块
          current_read_pos += bytes_read.to_int64()
      }
    }

    // 确定最终的 end_pos
    let end_pos = match end_pos_opt {
      Some(pos) => pos
      None => file_size // 如果直到文件末尾都没找到换行符,则取文件末尾
    }

    offsets.push((last_pos, end_pos))
    last_pos = end_pos
  }

  // 处理最后一个块(如果还有剩余数据)
  if last_pos < file_size {
    offsets.push((last_pos, file_size))
  }

  Ok(offsets)
}

///|
// pub fn get_turtle_slice_chunks(
//   bytes : BytesView,
//   n_chunks : Int,
//   parser : TurtleParser,
// ) -> Array[(Int, Int)] {
//   // 边界检查
//   if n_chunks <= 0 {
//     return [(0, bytes.length())]
//   }

//   let total_len = bytes.length()
//   if total_len == 0 {
//     return []
//   }

//   // 最小块大小至少为 1
//   let chunk_size = (total_len / n_chunks).max(1)

//   let mut last_pos = 0
//   let offsets = Array::new(capacity=n_chunks)

//   for _ in 0..= total_len {
//       break
//     }

//     // 从 search_pos 开始搜索到末尾
//     let remaining = bytes[search_pos:total_len]
//     match next_terminating_char(parser, remaining) {
//       Some(pos) => {
//         // pos 是相对于 search_pos 的偏移
//         let end_pos = search_pos + pos
//         offsets.push((last_pos, end_pos))
//         last_pos = end_pos
//       }
//       None => {
//         // 找不到终止符:将剩余所有内容作为最后一块
//         offsets.push((last_pos, total_len))
//         last_pos = total_len
//         break
//       }
//     }
//   }

//   // 添加最后一块
//   if last_pos < total_len {
//     offsets.push((last_pos, total_len))
//   }

//   offsets
// }
pub fn get_turtle_slice_chunks(
  bytes : BytesView,
  n_chunks : Int,
) -> Array[(Int, Int)] {
  // 按换行符分割,简单高效
  get_ntriples_slice_chunks(bytes, n_chunks)
}

///|
pub fn next_terminating_char(parser : TurtleParser, input : BytesView) -> Int? {
  let mut input = input
  let mut total_pos = 0

  for _ in 0..<1_000 {
    // 安全地查找 '.'
    match memchr(b'.', input) {
      Some(dot_index) => {
        let pos = dot_index + 1
        if pos >= input.length() {
          return None
        }
        let new_input = input[pos:]
        let p = parser
        let accepted = accept(p, new_input)
        if accepted {
          return Some(total_pos + pos)
        }
        // 如果未接受,跳过这个 '.' 继续寻找下一个
        input = input[pos:] // 注意:这里应该是 pos 还是 pos+1 取决于逻辑,原代码是 pos+1
        total_pos += pos
      }
      None =>
        // 如果没有找到 '.',则无法在此处分割
        return None
    }
  }
  None
}

///|
fn accept(parser : TurtleParser, input : BytesView) -> Bool {
  let f = parser.for_slice(input)
  let iter_opt = f.inner.next()
  for _ in 0..<3 {
    if iter_opt is Some(_r) {
      // ... 只检查第一个结果
      break
    } else {
      return false
    }
  }
  true
}