// ============================================================
// CSV
// ============================================================

///|
/// 按行读取 CSV,返回「行 → 字段」的二维数组
pub fn read_csv_by_line(
  file_path : String,
  encoding? : Encoding? = None,
) -> Array[Array[String]] raise ReaderError {
  let content = read_txt(file_path, encoding~)
  let chars = content.iter().to_array()
  let n = chars.length()
  let records : Array[Array[String]] = []
  let mut record : Array[String] = []
  let mut field = ""
  let mut in_quotes = false
  let mut i = 0
  while i < n {
    let c = chars[i]
    if in_quotes {
      if c == '"' {
        if i + 1 < n && chars[i + 1] == '"' {
          field = field + "\""
          i = i + 1
        } else {
          in_quotes = false
        }
      } else {
        field = field + c.to_string()
      }
    } else if c == '"' {
      in_quotes = true
    } else if c == ',' {
      record.push(field)
      field = ""
    } else if c == '\n' {
      record.push(field)
      records.push(record)
      record = []
      field = ""
    } else if c == '\r' {
      // 忽略 CR,兼容 CRLF
    } else {
      field = field + c.to_string()
    }
    i = i + 1
  }
  // 最后一个字段 / 记录(若文件不以换行结尾)
  if field != "" || record.length() > 0 {
    record.push(field)
    records.push(record)
  }
  records
}

///|
/// 按列读取 CSV:返回「列 → 值」的二维数组(转置)
pub fn read_csv_by_column(
  file_path : String,
  encoding? : Encoding? = None,
) -> Array[Array[String]] raise ReaderError {
  let rows = read_csv_by_line(file_path, encoding~)
  if rows.length() == 0 {
    return []
  }
  let ncols = rows[0].length()
  let cols : Array[Array[String]] = []
  let mut i = 0
  while i < ncols {
    let col : Array[String] = []
    for row in rows {
      if i < row.length() {
        col.push(row[i])
      } else {
        col.push("")
      }
    }
    cols.push(col)
    i = i + 1
  }
  cols
}

///|
/// 按块读取 CSV:每 block_size 行一个块
pub fn read_csv_by_block(
  file_path : String,
  block_size : Int,
  encoding? : Encoding? = None,
) -> Array[Array[Array[String]]] raise ReaderError {
  let rows = read_csv_by_line(file_path, encoding~)
  let blocks : Array[Array[Array[String]]] = []
  let mut cur : Array[Array[String]] = []
  for row in rows {
    cur.push(row)
    if cur.length() == block_size {
      blocks.push(cur)
      cur = []
    }
  }
  if cur.length() > 0 {
    blocks.push(cur)
  }
  blocks
}