//! Debug INSERT query handling - check if we detect INSERT statements
//! and whether target columns are available.

use datafusion::sql::sqlparser::ast::Statement;
use datafusion::sql::sqlparser::dialect::SnowflakeDialect;
use datafusion::sql::sqlparser::parser::Parser;
use serde::Deserialize;
use std::collections::HashMap;
use std::io::BufRead;
use std::path::Path;

#[derive(Deserialize)]
struct Case {
    #[allow(dead_code)]
    name: String,
    sql: String,
    schema: serde_json::Value,
    expected: HashMap<String, Vec<String>>,
}

fn main() {
    let fixture_path = Path::new("tests/fixtures/lineage/snowflake_ground_truth.jsonl");
    let file = std::fs::File::open(&fixture_path).expect("open");
    let reader = std::io::BufReader::with_capacity(1024 * 1024, file);
    let dialect = SnowflakeDialect {};

    let mut total = 0u64;
    let mut insert_count = 0u64;
    let mut insert_with_cols = 0u64;
    let mut insert_without_cols = 0u64;
    let mut target_in_schema = 0u64;
    let mut target_not_in_schema = 0u64;
    let mut expected_subset_of_schema = 0u64;

    let mut samples = Vec::new();

    for line in reader.lines() {
        let line = line.unwrap();
        let line = line.trim();
        if line.is_empty() {
            continue;
        }
        let case: Case = match serde_json::from_str(line) {
            Ok(c) => c,
            Err(_) => continue,
        };
        total += 1;

        let stmts = match Parser::parse_sql(&dialect, &case.sql) {
            Ok(s) => s,
            Err(_) => continue,
        };

        for stmt in &stmts {
            if let Statement::Insert(ins) = stmt {
                insert_count += 1;
                if ins.columns.is_empty() {
                    insert_without_cols += 1;
                } else {
                    insert_with_cols += 1;
                }

                // Check if target table is in schema
                let target = ins.table.to_string();
                let target_clean = target
                    .split('.')
                    .last()
                    .unwrap_or(&target)
                    .trim_matches('"')
                    .to_string();

                let schema_tables: Vec<String> = match &case.schema {
                    serde_json::Value::Object(map) => map.keys().cloned().collect(),
                    _ => vec![],
                };
                let target_lower = target_clean.to_lowercase();
                let found = schema_tables
                    .iter()
                    .any(|t| t.to_lowercase() == target_lower);
                if found {
                    target_in_schema += 1;
                } else {
                    target_not_in_schema += 1;
                }

                // Check if expected columns are a subset of schema columns
                if found {
                    if let Some(serde_json::Value::Object(table_obj)) = schema_tables
                        .iter()
                        .find(|t| t.to_lowercase() == target_lower)
                        .and_then(|t| case.schema.get(t))
                    {
                        let schema_cols: std::collections::HashSet<String> =
                            table_obj.keys().map(|k| k.to_uppercase()).collect();
                        let expected_cols: std::collections::HashSet<String> =
                            case.expected.keys().map(|k| k.to_uppercase()).collect();
                        if expected_cols.is_subset(&schema_cols) {
                            expected_subset_of_schema += 1;
                        }
                    }
                }

                if samples.len() < 3 {
                    let insert_cols: Vec<String> =
                        ins.columns.iter().map(|c| c.value.clone()).collect();
                    samples.push((
                        case.name.clone(),
                        target.clone(),
                        insert_cols,
                        schema_tables.clone(),
                        case.expected.keys().cloned().collect::<Vec<_>>(),
                    ));
                }
            }
        }
    }

    println!("Total queries:         {total}");
    println!("INSERT queries:        {insert_count}");
    println!("  with explicit cols:  {insert_with_cols}");
    println!("  without cols:        {insert_without_cols}");
    println!("Target in schema:      {target_in_schema}");
    println!("Target NOT in schema:  {target_not_in_schema}");
    println!("Expected subset of schema: {expected_subset_of_schema}");

    println!("\n=== Samples ===");
    for (name, target, cols, schema_tables, expected_keys) in &samples {
        println!("Name: {name}");
        println!("  Target table: {target}");
        println!("  INSERT cols: {:?}", cols);
        println!("  Schema tables: {:?}", schema_tables);
        println!("  Expected keys: {:?}", expected_keys);
        println!();
    }
}
