#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script para ejecutar los tests del catálogo de parámetros
"""

import odoo
import logging
from odoo.tests.common import TransactionCase
from odoo.tests import tagged

_logger = logging.getLogger(__name__)

def run_parameter_catalog_tests(db_name='lims_demo'):
    """Ejecuta todos los tests del catálogo de parámetros"""
    
    print("\n" + "="*70)
    print("EJECUTANDO TESTS DEL CATÁLOGO DE PARÁMETROS")
    print("="*70 + "\n")
    
    # Importar los tests
    try:
        from odoo.addons.lims_management.tests import (
            test_analysis_parameter,
            test_parameter_range,
            test_result_parameter_integration,
            test_auto_result_generation
        )
        print("✓ Tests importados correctamente\n")
    except ImportError as e:
        print(f"✗ Error importando tests: {e}")
        return
    
    # Lista de clases de test a ejecutar
    test_classes = [
        (test_analysis_parameter.TestAnalysisParameter, "Parámetros de Análisis"),
        (test_parameter_range.TestParameterRange, "Rangos de Referencia"),
        (test_result_parameter_integration.TestResultParameterIntegration, "Integración Resultados-Parámetros"),
        (test_auto_result_generation.TestAutoResultGeneration, "Generación Automática de Resultados"),
    ]
    
    # Conectar a la base de datos
    registry = odoo.registry(db_name)
    
    # Ejecutar cada conjunto de tests
    total_tests = 0
    passed_tests = 0
    failed_tests = 0
    
    for test_class, test_name in test_classes:
        print(f"\n--- Ejecutando tests de {test_name} ---")
        
        with registry.cursor() as cr:
            env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
            
            # Crear instancia del test
            test_instance = test_class()
            test_instance.env = env
            test_instance.cr = cr
            test_instance.uid = odoo.SUPERUSER_ID
            
            # Obtener todos los métodos de test
            test_methods = [method for method in dir(test_instance) 
                          if method.startswith('test_')]
            
            for method_name in test_methods:
                total_tests += 1
                try:
                    # Ejecutar setUp
                    test_instance.setUp()
                    
                    # Ejecutar el test
                    method = getattr(test_instance, method_name)
                    method()
                    
                    print(f"  ✓ {method_name}")
                    passed_tests += 1
                    
                except Exception as e:
                    print(f"  ✗ {method_name}: {str(e)}")
                    failed_tests += 1
                    _logger.exception(f"Test failed: {method_name}")
                
                finally:
                    # Rollback para no afectar otros tests
                    cr.rollback()
    
    # Resumen final
    print("\n" + "="*70)
    print("RESUMEN DE TESTS")
    print("="*70)
    print(f"Total de tests ejecutados: {total_tests}")
    print(f"✓ Tests exitosos: {passed_tests}")
    print(f"✗ Tests fallidos: {failed_tests}")
    
    if failed_tests == 0:
        print("\n✅ TODOS LOS TESTS PASARON EXITOSAMENTE")
    else:
        print(f"\n⚠️  {failed_tests} TESTS FALLARON")
    
    return failed_tests == 0


def run_specific_test(db_name='lims_demo', test_module=None, test_method=None):
    """Ejecuta un test específico para debugging"""
    
    if not test_module:
        print("Debe especificar el módulo de test")
        return
    
    print(f"\nEjecutando test específico: {test_module}")
    if test_method:
        print(f"Método: {test_method}")
    
    # Importar el módulo de test
    exec(f"from odoo.addons.lims_management.tests import {test_module}")
    module = eval(test_module)
    
    # Encontrar la clase de test
    test_class = None
    for item in dir(module):
        obj = getattr(module, item)
        if isinstance(obj, type) and issubclass(obj, TransactionCase) and obj != TransactionCase:
            test_class = obj
            break
    
    if not test_class:
        print("No se encontró clase de test en el módulo")
        return
    
    registry = odoo.registry(db_name)
    
    with registry.cursor() as cr:
        env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
        
        test_instance = test_class()
        test_instance.env = env
        test_instance.cr = cr
        test_instance.uid = odoo.SUPERUSER_ID
        
        if test_method:
            # Ejecutar método específico
            if hasattr(test_instance, test_method):
                try:
                    test_instance.setUp()
                    method = getattr(test_instance, test_method)
                    method()
                    print(f"✓ Test {test_method} pasó exitosamente")
                except Exception as e:
                    print(f"✗ Test {test_method} falló: {str(e)}")
                    import traceback
                    traceback.print_exc()
            else:
                print(f"Método {test_method} no encontrado")
        else:
            # Ejecutar todos los métodos del módulo
            test_methods = [m for m in dir(test_instance) if m.startswith('test_')]
            for method_name in test_methods:
                try:
                    test_instance.setUp()
                    method = getattr(test_instance, method_name)
                    method()
                    print(f"✓ {method_name}")
                except Exception as e:
                    print(f"✗ {method_name}: {str(e)}")
                finally:
                    cr.rollback()


if __name__ == '__main__':
    import sys
    
    # Verificar argumentos
    if len(sys.argv) > 1:
        if sys.argv[1] == '--specific':
            # Modo de test específico
            module = sys.argv[2] if len(sys.argv) > 2 else None
            method = sys.argv[3] if len(sys.argv) > 3 else None
            run_specific_test(test_module=module, test_method=method)
        else:
            # Usar base de datos especificada
            run_parameter_catalog_tests(db_name=sys.argv[1])
    else:
        # Ejecutar todos los tests con DB por defecto
        success = run_parameter_catalog_tests()
        sys.exit(0 if success else 1)