///|
/// sqlite_schema 的一条已校验记录。root_page 为 0 表示无独立根页;sql 可为空,不解析 CREATE 语句,也不恢复列名或 SQL 语义。
pub(all) struct SchemaEntry {
  object_type : String
  name : String
  table_name : String
  root_page : Int
  sql : String?
} derive(Debug)

///|
pub extend SchemaEntry with @debug.Debug::{to_repr}

///|
/// 异步适配层校验已解码的 sqlite_schema 记录,语义与同步 schema 一致。
/// 校验一条已解码 sqlite_schema record 和根页范围;不解析 sql 字符串,page_count 必须是视图的逻辑页数。
pub fn decode_schema_entry(
  values : Array[Value],
  page_count : Int,
) -> SchemaEntry raise SqliteError {
  schema_entry(values, page_count)
}

///|
/// 完整读取并校验 sqlite_schema;受 Limits.max_rows 预算限制,超出时抛 LimitExceeded,不把 schema 前缀冒充完整对象集合。
pub fn Database::schema(
  self : Database,
) -> Array[SchemaEntry] raise SqliteError {
  let entries : Array[SchemaEntry] = []
  for row in self.read_table(1) {
    entries.push(schema_entry(row.values, self.page_count))
  }
  entries
}

///|
fn schema_entry(
  values : Array[Value],
  page_count : Int,
) -> SchemaEntry raise SqliteError {
  match values {
    [Text(object_type), Text(name), Text(table_name), root_value, sql_value] => {
      let root = match root_value {
        Integer(value) => value
        Null => 0L
        _ => raise Invalid("schema rootpage 字段类型无效")
      }
      if root < 0L || root > page_count.to_int64() {
        raise Invalid("schema root page 越界")
      }
      if object_type != "table" &&
        object_type != "index" &&
        object_type != "view" &&
        object_type != "trigger" {
        raise Invalid("schema 包含未知对象类型")
      }
      let sql = match sql_value {
        Text(value) => Some(value)
        Null => None
        _ => raise Invalid("schema SQL 字段类型无效")
      }
      { object_type, name, table_name, root_page: root.to_int(), sql, }
    }
    _ => raise Invalid("sqlite_schema 记录不包含标准五列")
  }
}

///|
/// 按 schema 名称读取普通 rowid 表;不执行 SELECT,也不恢复 INTEGER PRIMARY KEY 磁盘 Null 字段,WITHOUT ROWID 请用 table_records。
pub fn Database::table_rows(
  self : Database,
  name : String,
  limit? : Int = self.limits.max_rows,
) -> Array[Row] raise SqliteError {
  if name == "sqlite_schema" || name == "sqlite_master" {
    return self.read_table(1, limit~)
  }
  for entry in self.schema() {
    if entry.object_type == "table" && entry.name == name {
      if entry.root_page == 0 {
        raise Unsupported("虚拟表没有独立数据 B-tree")
      }
      return self.read_table(entry.root_page, limit~)
    }
  }
  raise Invalid("未找到表:\{name}")
}

///|
/// 返回普通表或 WITHOUT ROWID 表的原始存储记录,不推断 SQL 列顺序。
/// 按表名读取原始记录,包含 WITHOUT ROWID;values 保留存储顺序,显式 limit 可返回前缀。
pub fn Database::table_records(
  self : Database,
  name : String,
  limit? : Int = self.limits.max_rows,
) -> Array[BTreeRecord] raise SqliteError {
  if name == "sqlite_schema" || name == "sqlite_master" {
    return self.read_btree(1, limit~)
  }
  for entry in self.schema() {
    if entry.object_type == "table" && entry.name == name {
      if entry.root_page == 0 {
        raise Unsupported("虚拟表没有独立数据 B-tree")
      }
      return self.read_btree(entry.root_page, limit~)
    }
  }
  raise Invalid("未找到表:\{name}")
}

///|
/// 按索引名读取包含内部 cell 的原始记录;不验证排序、collation 或表/索引内容一致性。
pub fn Database::index_records(
  self : Database,
  name : String,
  limit? : Int = self.limits.max_rows,
) -> Array[BTreeRecord] raise SqliteError {
  for entry in self.schema() {
    if entry.object_type == "index" && entry.name == name {
      if entry.root_page == 0 {
        raise Invalid("索引没有有效根页")
      }
      return self.read_index(entry.root_page, limit~)
    }
  }
  raise Invalid("未找到索引:\{name}")
}