mod functions;
mod misc;
mod tables;
mod types_;
pub(crate) mod util;
mod views;

use pg_query::NodeEnum;

use crate::{core::schema::SchemaModel, parse::ParsedStatement};

pub(crate) use tables::range_var_to_key;

/// Walk `stmts` for DDL nodes and populate `model`.
///
/// Unknown or unhandled node variants are logged at `DEBUG` and skipped.
pub fn walk_ddl(stmts: &[ParsedStatement], model: &mut SchemaModel) {
    for stmt in stmts {
        match &stmt.root {
            NodeEnum::CreateStmt(s) => {
                tracing::trace!(node = "CreateStmt", "handling DDL node");
                tables::handle_create_table(s, stmt.range, model);
            }
            NodeEnum::CreateFunctionStmt(s) => {
                tracing::trace!(node = "CreateFunctionStmt", "handling DDL node");
                functions::handle_create_function(s, stmt.range, model);
            }
            NodeEnum::ViewStmt(s) => {
                tracing::trace!(node = "ViewStmt", "handling DDL node");
                views::handle_view(s, stmt.range, model);
            }
            NodeEnum::CreateEnumStmt(s) => {
                tracing::trace!(node = "CreateEnumStmt", "handling DDL node");
                types_::handle_create_enum(s, stmt.range, model);
            }
            NodeEnum::CompositeTypeStmt(s) => {
                tracing::trace!(node = "CompositeTypeStmt", "handling DDL node");
                types_::handle_composite_type(s, stmt.range, model);
            }
            NodeEnum::CommentStmt(s) => {
                tracing::trace!(node = "CommentStmt", "handling DDL node");
                misc::handle_comment(s, model);
            }
            NodeEnum::AlterTableStmt(s) => {
                tracing::trace!(node = "AlterTableStmt", "handling DDL node");
                tables::handle_alter_table(s, stmt.range.start(), model);
            }
            NodeEnum::CreateTrigStmt(s) => {
                tracing::trace!(node = "CreateTrigStmt", "handling DDL node");
                misc::handle_create_trigger(s, stmt.range, model);
            }
            NodeEnum::CreatePolicyStmt(s) => {
                tracing::trace!(node = "CreatePolicyStmt", "handling DDL node");
                misc::handle_create_policy(s, stmt.range, model);
            }
            NodeEnum::IndexStmt(s) => {
                tracing::trace!(node = "IndexStmt", "handling DDL node");
                misc::handle_create_index(s, stmt.range, model);
            }
            other => {
                tracing::debug!(node = ?std::mem::discriminant(other), "skipping unhandled DDL node");
            }
        }
    }
}
