#!/usr/bin/env python3
"""
Flyway Migration Checks Module

Checks Flyway migration status and validates schema consistency.
"""

import subprocess
import sys
from pathlib import Path
from tests.utils.logger import Logger


class FlywayChecks:
    """Flyway migration checks for StreamA2026"""
    
    def __init__(self, logger: Logger, project_dir: str, version: str = "unknown"):
        self.logger = logger
        self.version = version
        self.project_dir = Path(project_dir)
        self.flyway_dir = self.project_dir / "flyway" / "sql"
    
    def run_all_checks(self) -> bool:
        """Run all Flyway checks"""
        self.logger.subheader(f"Flyway Migration Checks (v{self.version})")
        
        all_passed = True
        
        # Check 1: Flyway SQL directory exists
        if not self.check_flyway_directory():
            all_passed = False
        
        # Check 2: Baseline migration exists
        if not self.check_baseline_migration():
            all_passed = False
        
        # Check 3: Migration files follow naming convention
        if not self.check_migration_naming():
            all_passed = False
        
        # Check 4: Init-DB consistency with Flyway baseline
        if not self.check_init_db_consistency():
            all_passed = False
        
        # Check 5: Flyway container status (if running)
        if not self.check_flyway_container():
            all_passed = False
        
        return all_passed
    
    def check_flyway_directory(self) -> bool:
        """Check if Flyway SQL directory exists"""
        self.logger.info("FLYWAY", "Checking Flyway SQL directory...")
        
        if not self.flyway_dir.exists():
            self.logger.error("FLYWAY", f"Flyway SQL directory not found: {self.flyway_dir}")
            return False
        
        self.logger.success("FLYWAY", f"Flyway SQL directory exists: {self.flyway_dir}")
        return True
    
    def check_baseline_migration(self) -> bool:
        """Check if baseline migration (V1__baseline.sql) exists"""
        self.logger.info("FLYWAY", "Checking baseline migration...")
        
        baseline = self.flyway_dir / "V1__baseline.sql"
        
        if not baseline.exists():
            self.logger.error("FLYWAY", f"Baseline migration not found: {baseline}")
            return False
        
        self.logger.success("FLYWAY", f"Baseline migration exists: {baseline}")
        return True
    
    def check_migration_naming(self) -> bool:
        """Check if migration files follow Flyway naming convention"""
        self.logger.info("FLYWAY", "Checking migration naming convention...")
        
        migration_files = list(self.flyway_dir.glob("*.sql"))
        
        if not migration_files:
            self.logger.warning("FLYWAY", "No migration files found in Flyway SQL directory")
            return True  # Not an error, just a warning
        
        invalid_files = []
        for migration_file in migration_files:
            filename = migration_file.name
            
            # Flyway naming convention: V<version>__<description>.sql
            # Example: V1__baseline.sql, V2__add_column.sql
            if not (filename.startswith("V") and "__" in filename and filename.endswith(".sql")):
                invalid_files.append(filename)
        
        if invalid_files:
            self.logger.error("FLYWAY", f"Invalid migration file names: {', '.join(invalid_files)}")
            self.logger.info("FLYWAY", "Expected format: V<version>__<description>.sql")
            return False
        
        self.logger.success("FLYWAY", f"All {len(migration_files)} migration files follow naming convention")
        return True
    
    def check_init_db_consistency(self) -> bool:
        """Check if baseline migration exists (init-db.sql no longer needed)"""
        self.logger.info("FLYWAY", "Checking baseline migration...")
        
        baseline = self.flyway_dir / "V1__baseline.sql"
        
        if not baseline.exists():
            self.logger.warning("FLYWAY", "Baseline migration not found")
            return False
        
        self.logger.success("FLYWAY", "Baseline migration exists (init-db.sql no longer needed)")
        return True
    
    def check_flyway_container(self) -> bool:
        """Check if Flyway container is running (optional)"""
        self.logger.info("FLYWAY", "Checking Flyway container status...")
        
        try:
            # Check if Flyway container exists and is running
            result = subprocess.run(
                ["docker", "compose", "ps", "flyway"],
                capture_output=True,
                text=True,
                cwd=self.project_dir
            )
            
            if "streama2026-flyway" in result.stdout and "Up" in result.stdout:
                self.logger.success("FLYWAY", "Flyway container is running")
                return True
            else:
                self.logger.info("FLYWAY", "Flyway container is not running (this is OK if not using Flyway yet)")
                return True  # Not an error, just informational
        
        except Exception as e:
            self.logger.warning("FLYWAY", f"Could not check Flyway container: {e}")
            return True  # Not an error, just informational
