#!/usr/bin/env python3
"""
Migration Squash Script

This script squashes all existing migrations into a single initial migration.
Run this after setting up PostgreSQL to simplify the migration history.

Prerequisites:
- PostgreSQL must be running: make docker-up
- DATABASE_URL environment variable must be set to PostgreSQL

Usage:
    python scripts/squash_migrations.py

What this script does:
1. Backs up existing migrations to alembic/versions_backup_YYYYMMDD/
2. Creates a fresh initial migration from current models
3. Stamps the database as being at the new migration

After running:
1. Review the new migration in alembic/versions/
2. Test with: make migrate-up (on a fresh database)
3. If satisfied, delete the backup directory
"""

import os
import shutil
import subprocess
import sys
from datetime import datetime
from pathlib import Path

# Add project root to path
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

VERSIONS_DIR = project_root / "alembic" / "versions"


def check_prerequisites():
    """Verify PostgreSQL is configured."""
    database_url = os.getenv("DATABASE_URL", "")

    if not database_url.startswith("postgresql"):
        print("ERROR: DATABASE_URL must be a PostgreSQL URL")
        print(f"Current: {database_url[:50]}...")
        print("")
        print("Set DATABASE_URL or start PostgreSQL with: make docker-up")
        sys.exit(1)

    print(f"Database: {database_url.split('@')[0]}@...")
    return True


def backup_migrations():
    """Backup existing migrations."""
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    backup_dir = project_root / "alembic" / f"versions_backup_{timestamp}"

    if not VERSIONS_DIR.exists():
        print("No existing migrations to backup")
        return None

    migration_files = list(VERSIONS_DIR.glob("*.py"))
    if not migration_files:
        print("No migration files found")
        return None

    print(f"Backing up {len(migration_files)} migrations to {backup_dir.name}/")
    shutil.copytree(VERSIONS_DIR, backup_dir)

    # Clear versions directory (keep __pycache__ if exists)
    for f in VERSIONS_DIR.glob("*.py"):
        f.unlink()

    return backup_dir


def create_fresh_migration():
    """Generate fresh initial migration from models."""
    print("Generating fresh initial migration...")

    result = subprocess.run(
        [
            sys.executable, "-m", "alembic", "revision",
            "--autogenerate", "-m", "initial_postgresql_schema"
        ],
        cwd=project_root,
        capture_output=True,
        text=True
    )

    if result.returncode != 0:
        print("ERROR: Failed to generate migration")
        print(result.stderr)
        sys.exit(1)

    print(result.stdout)

    # Find the new migration file
    new_migrations = list(VERSIONS_DIR.glob("*initial_postgresql_schema*.py"))
    if new_migrations:
        print(f"Created: {new_migrations[0].name}")
        return new_migrations[0]

    return None


def clean_migration_file(migration_path: Path):
    """Remove SQLite-specific patterns from migration."""
    if not migration_path:
        return

    content = migration_path.read_text()

    # Remove batch_alter_table references (not needed for PostgreSQL)
    if "batch_alter_table" in content:
        print("Note: Migration contains batch_alter_table - this is not needed for PostgreSQL")
        # We don't auto-remove as it might be intentional

    print(f"Review migration at: {migration_path}")


def stamp_database():
    """Stamp the database as being at the new migration."""
    print("Stamping database with new migration...")

    result = subprocess.run(
        [sys.executable, "-m", "alembic", "stamp", "head"],
        cwd=project_root,
        capture_output=True,
        text=True
    )

    if result.returncode != 0:
        print("WARNING: Could not stamp database (may need to run migrate-up first)")
        print(result.stderr)
    else:
        print("Database stamped at head")


def main():
    print("=" * 60)
    print("MIGRATION SQUASH SCRIPT")
    print("=" * 60)
    print("")

    # Check prerequisites
    check_prerequisites()
    print("")

    # Confirm with user
    response = input("This will backup and replace all migrations. Continue? [y/N] ")
    if response.lower() != 'y':
        print("Aborted")
        sys.exit(0)

    print("")

    # Backup existing migrations
    backup_dir = backup_migrations()
    print("")

    # Create fresh migration
    new_migration = create_fresh_migration()
    print("")

    # Clean up the migration file
    clean_migration_file(new_migration)
    print("")

    # Summary
    print("=" * 60)
    print("SQUASH COMPLETE")
    print("=" * 60)
    print("")
    if backup_dir:
        print(f"Backup location: {backup_dir}")
    print("")
    print("Next steps:")
    print("1. Review the new migration file")
    print("2. On a fresh database, run: make migrate-up")
    print("3. Verify all tables are created correctly")
    print("4. If satisfied, delete the backup directory")
    print("")
    print("To restore from backup:")
    print(f"  rm -rf alembic/versions/*.py")
    print(f"  cp -r {backup_dir}/* alembic/versions/")


if __name__ == "__main__":
    main()
