"""dev_tools initial - test runs, architecture scans, violations

Revision ID: dev_tools_001
Revises: loyalty_001
Create Date: 2026-02-07
"""
import sqlalchemy as sa

from alembic import op

revision = "dev_tools_001"
down_revision = "loyalty_002"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # --- test_runs ---
    op.create_table(
        "test_runs",
        sa.Column("id", sa.Integer(), primary_key=True, index=True),
        sa.Column("timestamp", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False, index=True),
        sa.Column("total_tests", sa.Integer(), nullable=True),
        sa.Column("passed", sa.Integer(), nullable=True),
        sa.Column("failed", sa.Integer(), nullable=True),
        sa.Column("errors", sa.Integer(), nullable=True),
        sa.Column("skipped", sa.Integer(), nullable=True),
        sa.Column("xfailed", sa.Integer(), nullable=True),
        sa.Column("xpassed", sa.Integer(), nullable=True),
        sa.Column("coverage_percent", sa.Float(), nullable=True),
        sa.Column("duration_seconds", sa.Float(), nullable=True),
        sa.Column("triggered_by", sa.String(100), nullable=True),
        sa.Column("git_commit_hash", sa.String(40), nullable=True),
        sa.Column("git_branch", sa.String(100), nullable=True),
        sa.Column("test_path", sa.String(500), nullable=True),
        sa.Column("pytest_args", sa.String(500), nullable=True),
        sa.Column("status", sa.String(20), nullable=True, server_default="running", index=True),
        sa.Column("celery_task_id", sa.String(255), nullable=True, index=True),
    )

    # --- test_results ---
    op.create_table(
        "test_results",
        sa.Column("id", sa.Integer(), primary_key=True, index=True),
        sa.Column("run_id", sa.Integer(), sa.ForeignKey("test_runs.id"), nullable=False, index=True),
        sa.Column("node_id", sa.String(500), nullable=False, index=True),
        sa.Column("test_name", sa.String(200), nullable=False),
        sa.Column("test_file", sa.String(300), nullable=False),
        sa.Column("test_class", sa.String(200), nullable=True),
        sa.Column("outcome", sa.String(20), nullable=False, index=True),
        sa.Column("duration_seconds", sa.Float(), nullable=True),
        sa.Column("error_message", sa.Text(), nullable=True),
        sa.Column("traceback", sa.Text(), nullable=True),
        sa.Column("markers", sa.JSON(), nullable=True),
        sa.Column("parameters", sa.JSON(), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
    )

    # --- test_collections ---
    op.create_table(
        "test_collections",
        sa.Column("id", sa.Integer(), primary_key=True, index=True),
        sa.Column("total_tests", sa.Integer(), nullable=True),
        sa.Column("total_files", sa.Integer(), nullable=True),
        sa.Column("total_classes", sa.Integer(), nullable=True),
        sa.Column("unit_tests", sa.Integer(), nullable=True),
        sa.Column("integration_tests", sa.Integer(), nullable=True),
        sa.Column("performance_tests", sa.Integer(), nullable=True),
        sa.Column("system_tests", sa.Integer(), nullable=True),
        sa.Column("test_files", sa.JSON(), nullable=True),
        sa.Column("collected_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
    )

    # --- architecture_scans ---
    op.create_table(
        "architecture_scans",
        sa.Column("id", sa.Integer(), primary_key=True, index=True),
        sa.Column("timestamp", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False, index=True),
        sa.Column("validator_type", sa.String(20), nullable=False, server_default="architecture", index=True),
        sa.Column("status", sa.String(30), nullable=False, server_default="pending", index=True),
        sa.Column("started_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("error_message", sa.Text(), nullable=True),
        sa.Column("progress_message", sa.String(255), nullable=True),
        sa.Column("total_files", sa.Integer(), nullable=True),
        sa.Column("total_violations", sa.Integer(), nullable=True),
        sa.Column("errors", sa.Integer(), nullable=True),
        sa.Column("warnings", sa.Integer(), nullable=True),
        sa.Column("duration_seconds", sa.Float(), nullable=True),
        sa.Column("triggered_by", sa.String(100), nullable=True),
        sa.Column("git_commit_hash", sa.String(40), nullable=True),
        sa.Column("celery_task_id", sa.String(255), nullable=True, index=True),
    )

    # --- architecture_violations ---
    op.create_table(
        "architecture_violations",
        sa.Column("id", sa.Integer(), primary_key=True, index=True),
        sa.Column("scan_id", sa.Integer(), sa.ForeignKey("architecture_scans.id"), nullable=False, index=True),
        sa.Column("validator_type", sa.String(20), nullable=False, server_default="architecture", index=True),
        sa.Column("rule_id", sa.String(20), nullable=False, index=True),
        sa.Column("rule_name", sa.String(200), nullable=False),
        sa.Column("severity", sa.String(10), nullable=False, index=True),
        sa.Column("file_path", sa.String(500), nullable=False, index=True),
        sa.Column("line_number", sa.Integer(), nullable=False),
        sa.Column("message", sa.Text(), nullable=False),
        sa.Column("context", sa.Text(), nullable=True),
        sa.Column("suggestion", sa.Text(), nullable=True),
        sa.Column("status", sa.String(20), nullable=True, server_default="open", index=True),
        sa.Column("assigned_to", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
        sa.Column("resolved_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("resolved_by", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
        sa.Column("resolution_note", sa.Text(), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
    )

    # --- architecture_rules ---
    op.create_table(
        "architecture_rules",
        sa.Column("id", sa.Integer(), primary_key=True, index=True),
        sa.Column("rule_id", sa.String(20), unique=True, nullable=False, index=True),
        sa.Column("validator_type", sa.String(20), nullable=False, server_default="architecture", index=True),
        sa.Column("category", sa.String(50), nullable=False),
        sa.Column("name", sa.String(200), nullable=False),
        sa.Column("description", sa.Text(), nullable=True),
        sa.Column("severity", sa.String(10), nullable=False),
        sa.Column("enabled", sa.Boolean(), nullable=False, server_default="true"),
        sa.Column("custom_config", sa.JSON(), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
    )

    # --- violation_assignments ---
    op.create_table(
        "violation_assignments",
        sa.Column("id", sa.Integer(), primary_key=True, index=True),
        sa.Column("violation_id", sa.Integer(), sa.ForeignKey("architecture_violations.id"), nullable=False, index=True),
        sa.Column("user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=False),
        sa.Column("assigned_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
        sa.Column("assigned_by", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
        sa.Column("due_date", sa.DateTime(timezone=True), nullable=True),
        sa.Column("priority", sa.String(10), nullable=True),
    )

    # --- violation_comments ---
    op.create_table(
        "violation_comments",
        sa.Column("id", sa.Integer(), primary_key=True, index=True),
        sa.Column("violation_id", sa.Integer(), sa.ForeignKey("architecture_violations.id"), nullable=False, index=True),
        sa.Column("user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=False),
        sa.Column("comment", sa.Text(), nullable=False),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
    )


def downgrade() -> None:
    op.drop_table("violation_comments")
    op.drop_table("violation_assignments")
    op.drop_table("architecture_rules")
    op.drop_table("architecture_violations")
    op.drop_table("architecture_scans")
    op.drop_table("test_collections")
    op.drop_table("test_results")
    op.drop_table("test_runs")
