use super::*;

#[test]
fn renders_conflicting_sibling_for_each_dialect() {
    let query = conflicting_sibling_column_name(
        TableId(7),
        ColumnId(3),
        None,
        "Child's Name",
        SnapshotId(11),
    );

    assert!(query.render_embedded().contains("\"ducklake_column\""));
    assert!(
        query
            .render_embedded()
            .contains("CAST(?5 AS BIGINT) IS NULL")
    );

    let postgres = query.render_postgres("meta schema");
    assert!(postgres.contains("\"meta schema\".\"ducklake_column\""));
    assert!(postgres.contains("CAST($5 AS BIGINT) IS NULL"));

    let quack = query.render_quack();
    assert!(quack.contains("\"ducklake_column\""));
    assert!(quack.contains("CAST(NULL AS BIGINT) IS NULL"));
    assert!(quack.contains("'Child''s Name'"));

    let qualified_quack = query.render_quack_with_metadata_catalog(Some("ducklake meta"));
    assert!(qualified_quack.contains("\"ducklake meta\".\"ducklake_column\""));
    assert!(qualified_quack.contains("CAST(NULL AS BIGINT) IS NULL"));
}

#[test]
fn renders_metadata_rows_for_each_dialect() {
    let query = metadata_rows();

    assert_eq!(
        query.render_embedded(),
        "SELECT key, value, scope, scope_id FROM \"ducklake_metadata\""
    );
    assert_eq!(
        query.render_postgres("meta schema"),
        "SELECT key, value, scope, scope_id FROM \"meta schema\".\"ducklake_metadata\""
    );
    assert_eq!(
        query.render_quack(),
        "SELECT key, value, scope, scope_id FROM \"ducklake_metadata\""
    );
    assert_eq!(
        query.render_quack_with_metadata_catalog(Some("ducklake_meta")),
        "SELECT key, value, scope, scope_id FROM \"ducklake_meta\".\"ducklake_metadata\""
    );
}

#[test]
fn renders_placeholders_without_clobbering_prefixes() {
    let query = CatalogQuery::new(
        "SELECT ?1, ?10 FROM {ducklake_table}",
        vec![
            1.into(),
            2.into(),
            3.into(),
            4.into(),
            5.into(),
            6.into(),
            7.into(),
            8.into(),
            9.into(),
            10.into(),
        ],
    );
    assert_eq!(
        query.render_postgres("m"),
        "SELECT $1, $10 FROM \"m\".\"ducklake_table\""
    );
    assert_eq!(query.render_quack(), "SELECT 1, 10 FROM \"ducklake_table\"");
    assert_eq!(
        query.render_quack_with_metadata_catalog(Some("ducklake_meta")),
        "SELECT 1, 10 FROM \"ducklake_meta\".\"ducklake_table\""
    );
}

#[test]
fn quack_affected_count_probe_renders_separately_from_command() {
    let query = update_table_stats_for_append(TableId(7), 3, 3, 40);

    let command = query.render_quack_with_metadata_catalog(Some("ducklake_meta"));
    assert!(command.starts_with("UPDATE \"ducklake_meta\".\"ducklake_table_stats\""));
    assert!(!command.contains("RETURNING"));

    let affected = query
        .render_quack_affected_count_with_metadata_catalog(Some("ducklake_meta"))
        .unwrap();
    assert_eq!(
        affected,
        "SELECT COUNT(*) FROM \"ducklake_meta\".\"ducklake_table_stats\" WHERE table_id = 7"
    );
}

#[test]
fn render_numbered_placeholders_rewrites_all_indexes() {
    // Basic single-digit substitution.
    assert_eq!(
        render_numbered_placeholders("a = ?1 AND b = ?2", "$"),
        "a = $1 AND b = $2"
    );

    // Multi-digit indexes must not be clobbered by their prefixes (?1 vs ?12).
    assert_eq!(render_numbered_placeholders("?1 ?12 ?2", "$"), "$1 $12 $2");

    // Indexes beyond the old hard-coded cap of 32 must still be rewritten.
    assert_eq!(render_numbered_placeholders("?33 ?100", "$"), "$33 $100");

    // A `?` not followed by a digit is left untouched.
    assert_eq!(
        render_numbered_placeholders("json ->> 'k' = ?1", "$"),
        "json ->> 'k' = $1"
    );
    assert_eq!(
        render_numbered_placeholders("no placeholders", "$"),
        "no placeholders"
    );
}
