///|
/// 嵌套读取(shredded 输出)。对每个叶列返回"值 + definition level + repetition
/// level"逐槽对齐的三元组:`values[i]` 非空当且仅当 `def_levels[i] ==
/// max_definition_level`,`rep_levels[i] == 0` 表示第 i 槽开启一条新记录。
/// 记录(行 / list 条目 / map 条目)的装配由调用方按 schema 树完成,
/// 本文件只负责把页级编码正确展开成槽位流。

///|
pub(all) struct LeafColumn {
  /// 根到叶的路径(原始 schema 名,未规范化)
  path : Array[String]
  column_type : ColumnType
  max_definition_level : Int32
  max_repetition_level : Int32
  values : Array[Value]
  def_levels : Array[Int32]
  rep_levels : Array[Int32]
}

///|
fn count_levels_eq(levels : Array[Int32], target : Int32) -> Int32 {
  let mut n = 0
  for l in levels {
    if l == target {
      n = n + 1
    }
  }
  n
}

///|
/// 把密集非空值按 def level 回填成槽位流(def == max_def 取值,否则 Null)
fn pair_slots_shredded(
  slots : Array[Value],
  defs_out : Array[Int32],
  reps_out : Array[Int32],
  defs : Array[Int32],
  reps : Array[Int32],
  dense : Array[Value],
  max_definition_level : Int32,
  count : Int32,
) -> Unit raise ParquetError {
  if defs.length() != count || reps.length() != count {
    invalid_data(
      "Level count mismatch: def=\{defs.length()} rep=\{reps.length()} expected \{count}",
    )
  }
  let mut vi = 0
  for i in 0..= dense.length() {
        invalid_data("Not enough dense values for def levels")
      }
      slots.push(dense[vi])
      vi = vi + 1
    } else {
      slots.push(Null)
    }
    defs_out.push(defs[i])
    reps_out.push(reps[i])
  }
  if vi != dense.length() {
    invalid_data(
      "Dense value count mismatch: got \{dense.length()} expected \{vi}",
    )
  }
}

///|
fn decode_data_page_v1_shredded(
  slots : Array[Value],
  defs_out : Array[Int32],
  reps_out : Array[Int32],
  data : Bytes,
  payload_offset : Int32,
  header : DataPageHeaderMeta,
  column : LeafColumnMeta,
  dictionary : Array[Value]?,
) -> Unit raise ParquetError {
  // v1 页布局:[rep levels(有 4 字节长度前缀,仅 max_rep>0 时存在)]
  //           [def levels(同上,仅 max_def>0 时存在)] [密集值]
  let mut offset = payload_offset
  let reps : Array[Int32] = if column.max_repetition_level > 0 {
    let (r, consumed) = decode_levels_v1(
      data, offset, column.max_repetition_level, header.num_values,
    )
    offset = offset + consumed
    r
  } else {
    Array::make(header.num_values, 0)
  }
  let defs : Array[Int32] = if column.max_definition_level > 0 {
    let (d, consumed) = decode_levels_v1(
      data, offset, column.max_definition_level, header.num_values,
    )
    offset = offset + consumed
    d
  } else {
    Array::make(header.num_values, 0)
  }
  let non_null = count_levels_eq(defs, column.max_definition_level)
  let (dense, _) = decode_non_null_values(
    data, offset, header.encoding, column, non_null, dictionary,
  )
  pair_slots_shredded(
    slots, defs_out, reps_out, defs, reps, dense,
    column.max_definition_level, header.num_values,
  )
}

///|
fn decode_data_page_v2_shredded(
  slots : Array[Value],
  defs_out : Array[Int32],
  reps_out : Array[Int32],
  data : Bytes,
  payload_offset : Int32,
  header : DataPageHeaderV2Meta,
  column : LeafColumnMeta,
  dictionary : Array[Value]?,
  value_data : Bytes,
  value_offset : Int32,
) -> Unit raise ParquetError {
  // v2 页布局:levels 无长度前缀,字节数在页头;值段可能单独压缩(已在调用方解压)
  let reps : Array[Int32] = if column.max_repetition_level > 0 &&
    header.repetition_levels_byte_length > 0 {
    decode_rle_hybrid(
      data,
      payload_offset,
      bit_width(column.max_repetition_level),
      header.num_values,
      false,
    ).0
  } else {
    Array::make(header.num_values, 0)
  }
  let defs : Array[Int32] = if column.max_definition_level > 0 &&
    header.definition_levels_byte_length > 0 {
    decode_rle_hybrid(
      data,
      payload_offset + header.repetition_levels_byte_length,
      bit_width(column.max_definition_level),
      header.num_values,
      false,
    ).0
  } else {
    Array::make(header.num_values, 0)
  }
  let non_null = count_levels_eq(defs, column.max_definition_level)
  let (dense, _) = decode_non_null_values(
    value_data, value_offset, header.encoding, column, non_null, dictionary,
  )
  pair_slots_shredded(
    slots, defs_out, reps_out, defs, reps, dense,
    column.max_definition_level, header.num_values,
  )
}

///|
/// 解码单个列块(可含 repeated 层级),返回槽位流与对齐的 def/rep levels。
fn decode_column_chunk_shredded(
  data : Bytes,
  chunk : ColumnChunkMeta,
  column : LeafColumnMeta,
) -> (Array[Value], Array[Int32], Array[Int32]) raise ParquetError {
  let mut offset = chunk.meta_data.dictionary_page_offset
    .unwrap_or(chunk.meta_data.data_page_offset)
    .to_int()
  let target_values = chunk.meta_data.num_values.to_int()
  let slots : Array[Value] = Array(capacity=target_values)
  let defs : Array[Int32] = []
  let reps : Array[Int32] = []
  let mut dictionary : Array[Value]? = None
  while slots.length() < target_values {
    let (page_header, page_header_len) = read_page_header(data, offset)
    let payload_offset = offset + page_header_len
    if page_header.page_type == page_type_data_page {
      let payload = if chunk.meta_data.codec == codec_uncompressed {
        data
      } else {
        decompress_page_payload(
          data,
          payload_offset,
          page_header.compressed_page_size,
          page_header.uncompressed_page_size,
          chunk.meta_data.codec,
        )
      }
      let page_data_offset = if chunk.meta_data.codec == codec_uncompressed {
        payload_offset
      } else {
        0
      }
      match page_header.data_page {
        Some(data_page) =>
          decode_data_page_v1_shredded(
            slots, defs, reps, payload, page_data_offset, data_page, column,
            dictionary,
          )
        None => invalid_data("DATA_PAGE without data_page_header")
      }
    } else if page_header.page_type == page_type_data_page_v2 {
      match page_header.data_page_v2 {
        Some(data_page_v2) => {
          let value_offset = payload_offset +
            data_page_v2.repetition_levels_byte_length +
            data_page_v2.definition_levels_byte_length
          let compressed_value_len = page_header.compressed_page_size -
            data_page_v2.repetition_levels_byte_length -
            data_page_v2.definition_levels_byte_length
          let uncompressed_value_len = page_header.uncompressed_page_size -
            data_page_v2.repetition_levels_byte_length -
            data_page_v2.definition_levels_byte_length
          let (value_data, value_data_offset) = if data_page_v2.is_compressed &&
            chunk.meta_data.codec != codec_uncompressed {
            if compressed_value_len == 0 {
              (Default::default(), 0)
            } else {
              (
                decompress_page_payload(
                  data,
                  value_offset,
                  compressed_value_len,
                  uncompressed_value_len,
                  chunk.meta_data.codec,
                ),
                0,
              )
            }
          } else {
            (data, value_offset)
          }
          decode_data_page_v2_shredded(
            slots, defs, reps, data, payload_offset, data_page_v2, column,
            dictionary, value_data, value_data_offset,
          )
        }
        None => invalid_data("DATA_PAGE_V2 without data_page_header_v2")
      }
    } else if page_header.page_type == page_type_dictionary_page {
      let payload = if chunk.meta_data.codec == codec_uncompressed {
        data
      } else {
        decompress_page_payload(
          data,
          payload_offset,
          page_header.compressed_page_size,
          page_header.uncompressed_page_size,
          chunk.meta_data.codec,
        )
      }
      let page_data_offset = if chunk.meta_data.codec == codec_uncompressed {
        payload_offset
      } else {
        0
      }
      match page_header.dictionary_page {
        Some(dictionary_header) =>
          dictionary = Some(
            decode_dictionary_page(
              payload, page_data_offset, dictionary_header, column,
            ),
          )
        None => invalid_data("DICTIONARY_PAGE without dictionary_page_header")
      }
    } else {
      unsupported("Unsupported page type: \{page_header.page_type}")
    }
    offset = payload_offset + page_header.compressed_page_size
  }
  if slots.length() != target_values {
    invalid_data("Decoded slot count does not match column metadata")
  }
  (slots, defs, reps)
}

///|
/// 全文件 shredded 读取:返回每个叶列的槽位流与总记录数(跨 row group 拼接,
/// 记录边界由 rep==0 标记)。
pub fn read_bytes_shredded(
  data : Bytes,
) -> (Array[LeafColumn], Int32) raise ParquetError {
  check_magic(data)
  let footer_len = read_u32_le(data, data.length() - 8)
  let footer_start = data.length() - 8 - footer_len
  if footer_start < 4 {
    invalid_data("Invalid parquet footer length")
  }
  let metadata = read_file_metadata(data, footer_start, footer_len)
  let leaf_columns = build_leaf_columns(metadata.schema)
  let column_count = leaf_columns.length()
  let values : Array[Array[Value]] = Array::makei(column_count, fn(_) { [] })
  let defs : Array[Array[Int32]] = Array::makei(column_count, fn(_) { [] })
  let reps : Array[Array[Int32]] = Array::makei(column_count, fn(_) { [] })
  let mut total_rows = 0
  for row_group in metadata.row_groups {
    if row_group.columns.length() != column_count {
      invalid_data("RowGroup column count does not match schema leaf count")
    }
    total_rows = total_rows + row_group.num_rows.to_int()
    for column_index in 0..