//! Core validation bindings: validate, explain, fix, check_policy.

use crate::schema::Schema;
use pyo3::prelude::*;

/// Validate SQL against a schema. Returns a dict with `valid`, `errors`, `warnings`.
#[pyfunction]
pub fn validate(py: Python<'_>, sql: &str, schema: &Schema) -> PyResult<PyObject> {
    let start = std::time::Instant::now();
    let result = crate::runtime::runtime().block_on(altimate_core::validate(sql, &schema.inner));
    crate::sdk::timed_emit("validate", start);
    crate::convert::to_py_result(py, &result)
}

/// Explain a SQL query: plan steps, column lineage, cost signals.
#[pyfunction]
pub fn explain(py: Python<'_>, sql: &str, schema: &Schema) -> PyResult<PyObject> {
    let start = std::time::Instant::now();
    let result = crate::runtime::runtime().block_on(altimate_core::explain(sql, &schema.inner));
    crate::sdk::timed_emit("explain", start);
    crate::convert::to_py_result(py, &result)
}

/// Auto-fix SQL errors using fuzzy matching and iterative re-validation.
#[pyfunction]
#[pyo3(signature = (sql, schema, max_iterations=5))]
pub fn fix(
    py: Python<'_>,
    sql: &str,
    schema: &Schema,
    max_iterations: usize,
) -> PyResult<PyObject> {
    let config = altimate_core::fixer::types::FixConfig {
        max_iterations,
        ..Default::default()
    };
    let start = std::time::Instant::now();
    let result =
        crate::runtime::runtime().block_on(altimate_core::fix(sql, &schema.inner, &config));
    crate::sdk::timed_emit("fix", start);
    crate::convert::to_py_result(py, &result)
}

/// Check SQL against policy guardrails. `policy_json` is a JSON string of PolicyConfig.
#[pyfunction]
pub fn check_policy(
    py: Python<'_>,
    sql: &str,
    schema: &Schema,
    policy_json: &str,
) -> PyResult<PyObject> {
    let policy: altimate_core::PolicyConfig = serde_json::from_str(policy_json).map_err(|e| {
        pyo3::exceptions::PyValueError::new_err(format!("invalid policy JSON: {e}"))
    })?;
    let start = std::time::Instant::now();
    let result = crate::runtime::runtime().block_on(altimate_core::check_policy(
        sql,
        &schema.inner,
        &policy,
    ));
    crate::sdk::timed_emit("checkPolicy", start);
    crate::convert::to_py_result(py, &result)
}
