#!/usr/bin/env python3
"""
자동 마이그레이션 실행기 - 스키마 분석 결과를 바탕으로 자동으로 DB를 업데이트
"""

import os
import sys
import psycopg2
from psycopg2.extras import RealDictCursor
from datetime import datetime
from schema_analyzer import SchemaAnalyzer

class AutoMigrator:
    def __init__(self):
        self.db_config = {
            'host': 'localhost',
            'port': 5432,
            'database': 'tk_mp_bom',
            'user': 'tkmp_user',
            'password': 'tkmp_password'
        }
        self.analyzer = SchemaAnalyzer()
        self.migration_log = []

    def run_full_analysis_and_migration(self):
        """전체 분석 및 마이그레이션 실행"""
        print("🚀 자동 마이그레이션 시작")
        
        # 1. 스키마 분석
        print("\n1️⃣ 스키마 분석 중...")
        self.analyzer.analyze_code_models()
        self.analyzer.analyze_db_schema()
        analysis_result = self.analyzer.compare_schemas()
        
        # 2. 분석 결과 확인
        if not analysis_result['missing_tables'] and not analysis_result['missing_columns']:
            print("✅ 스키마가 이미 최신 상태입니다!")
            return True
        
        # 3. 마이그레이션 실행
        print("\n2️⃣ 마이그레이션 실행 중...")
        success = self._execute_migrations(analysis_result)
        
        # 4. 결과 로깅
        self._log_migration_result(success, analysis_result)
        
        return success

    def _execute_migrations(self, analysis_result) -> bool:
        """마이그레이션 실행"""
        try:
            conn = psycopg2.connect(**self.db_config)
            cursor = conn.cursor()
            
            # 트랜잭션 시작
            conn.autocommit = False
            
            # 1. 누락된 테이블 생성
            for table_name in analysis_result['missing_tables']:
                success = self._create_missing_table(cursor, table_name)
                if not success:
                    conn.rollback()
                    return False
            
            # 2. 누락된 컬럼 추가
            for missing_col in analysis_result['missing_columns']:
                success = self._add_missing_column(cursor, missing_col)
                if not success:
                    conn.rollback()
                    return False
            
            # 커밋
            conn.commit()
            cursor.close()
            conn.close()
            
            print("✅ 마이그레이션 성공!")
            return True
            
        except Exception as e:
            print(f"❌ 마이그레이션 실패: {e}")
            if 'conn' in locals():
                conn.rollback()
            return False

    def _create_missing_table(self, cursor, table_name: str) -> bool:
        """누락된 테이블 생성"""
        try:
            create_sql = self.analyzer._generate_create_table_sql(table_name)
            print(f"   📋 테이블 생성: {table_name}")
            cursor.execute(create_sql)
            
            self.migration_log.append({
                'type': 'CREATE_TABLE',
                'table': table_name,
                'sql': create_sql,
                'timestamp': datetime.now().isoformat()
            })
            
            return True
            
        except Exception as e:
            print(f"   ❌ 테이블 생성 실패 {table_name}: {e}")
            return False

    def _add_missing_column(self, cursor, missing_col: dict) -> bool:
        """누락된 컬럼 추가"""
        try:
            alter_sql = self.analyzer._generate_add_column_sql(missing_col)
            print(f"   🔧 컬럼 추가: {missing_col['table']}.{missing_col['column']}")
            cursor.execute(alter_sql)
            
            self.migration_log.append({
                'type': 'ADD_COLUMN',
                'table': missing_col['table'],
                'column': missing_col['column'],
                'sql': alter_sql,
                'timestamp': datetime.now().isoformat()
            })
            
            return True
            
        except Exception as e:
            print(f"   ❌ 컬럼 추가 실패 {missing_col['table']}.{missing_col['column']}: {e}")
            return False

    def _log_migration_result(self, success: bool, analysis_result: dict):
        """마이그레이션 결과 로깅"""
        log_entry = {
            'timestamp': datetime.now().isoformat(),
            'success': success,
            'analysis_result': analysis_result,
            'migration_log': self.migration_log
        }
        
        # 로그 파일에 저장
        import json
        log_filename = f"migration_log_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
        
        with open(log_filename, 'w', encoding='utf-8') as f:
            json.dump(log_entry, f, indent=2, ensure_ascii=False)
        
        print(f"📄 마이그레이션 로그 저장: {log_filename}")

    def fix_immediate_issues(self):
        """즉시 해결이 필요한 문제들 수정"""
        print("🔧 즉시 해결 필요한 문제들 수정 중...")
        
        immediate_fixes = [
            {
                'description': 'users 테이블에 status 컬럼 추가',
                'sql': "ALTER TABLE users ADD COLUMN status VARCHAR(20) DEFAULT 'active'",
                'check_sql': "SELECT column_name FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'status'"
            }
        ]
        
        try:
            conn = psycopg2.connect(**self.db_config)
            cursor = conn.cursor(cursor_factory=RealDictCursor)
            
            for fix in immediate_fixes:
                # 이미 존재하는지 확인
                cursor.execute(fix['check_sql'])
                if cursor.fetchone():
                    print(f"   ✅ 이미 존재: {fix['description']}")
                    continue
                
                # 수정 실행
                cursor.execute(fix['sql'])
                conn.commit()
                print(f"   🔧 수정 완료: {fix['description']}")
            
            cursor.close()
            conn.close()
            
            return True
            
        except Exception as e:
            print(f"❌ 즉시 수정 실패: {e}")
            return False

def main():
    migrator = AutoMigrator()
    
    # 1. 즉시 해결 필요한 문제들 수정
    migrator.fix_immediate_issues()
    
    # 2. 전체 분석 및 마이그레이션
    success = migrator.run_full_analysis_and_migration()
    
    if success:
        print("\n🎉 모든 마이그레이션이 성공적으로 완료되었습니다!")
    else:
        print("\n💥 마이그레이션 중 오류가 발생했습니다. 로그를 확인해주세요.")
    
    return success

if __name__ == "__main__":
    main()
