//! Result types for polyglot operations.

use serde::{Deserialize, Serialize};

/// Result of transpiling SQL from one dialect to another.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TranspileResult {
    /// The original SQL
    pub original_sql: String,
    /// Source dialect
    pub source_dialect: String,
    /// Target dialect
    pub target_dialect: String,
    /// Transpiled SQL statements
    pub transpiled_sql: Vec<String>,
    /// Whether transpilation succeeded
    pub success: bool,
    /// Error message if transpilation failed
    #[serde(skip_serializing_if = "Option::is_none")]
    pub error: Option<String>,
}

/// Result of extracting metadata from SQL.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExtractResult {
    /// Tables referenced in the query
    pub tables: Vec<String>,
    /// Columns referenced in the query
    pub columns: Vec<String>,
    /// Functions used in the query
    pub functions: Vec<String>,
    /// Whether the query contains subqueries
    pub has_subqueries: bool,
    /// Whether the query contains aggregation
    pub has_aggregation: bool,
    /// Whether the query contains window functions
    pub has_window_functions: bool,
    /// Total AST node count (complexity signal)
    pub node_count: usize,
}

/// Result of comparing two SQL queries.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompareResult {
    /// Whether the two queries are structurally identical
    pub identical: bool,
    /// Number of differences found
    pub diff_count: usize,
    /// Individual diff entries
    pub diffs: Vec<DiffEntry>,
}

/// A single difference between two SQL queries.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiffEntry {
    /// Type of change: "insert", "remove", "update", "move"
    pub change_type: String,
    /// Human-readable description of the change
    pub description: String,
}

/// Result of formatting SQL.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FormatResult {
    /// The original SQL
    pub original_sql: String,
    /// The formatted SQL
    pub formatted_sql: String,
    /// Dialect used for formatting
    pub dialect: String,
    /// Whether formatting succeeded
    pub success: bool,
    /// Error message if formatting failed
    #[serde(skip_serializing_if = "Option::is_none")]
    pub error: Option<String>,
}

/// Result of pre-validating SQL syntax with polyglot.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PrevalidateResult {
    /// Whether the SQL is syntactically valid for the dialect
    pub valid: bool,
    /// Validation errors if any
    pub errors: Vec<PrevalidateError>,
}

/// A single pre-validation error.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PrevalidateError {
    /// Error message
    pub message: String,
    /// Error code from polyglot
    pub code: String,
    /// Line number (1-based) if available
    #[serde(skip_serializing_if = "Option::is_none")]
    pub line: Option<usize>,
    /// Column number (1-based) if available
    #[serde(skip_serializing_if = "Option::is_none")]
    pub column: Option<usize>,
}
