#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script de prueba para verificar la conversión de ACTIONs LAD
"""

import sys
import os

# Agregar el directorio padre al path
sys.path.append('..')

# Importar el convertidor
from x1_lad_converter import SimpleLadConverter

def test_pattern_detection():
    """Probar la detección de patrones ??? vs Function Blocks directos"""
    print("=== TEST: Detección de patrones ??? vs Function Blocks ===")
    print("Basado en tu observación sobre los patrones LAD de TwinCAT")
    print("-" * 60)
    
    # Crear archivo de ejemplo que simule los patrones que identificaste
    test_content = """(* @PATH := '/TASK1_PID/PID_Controllers/Test_Program' *)
PROGRAM Test_Pattern_Program
VAR
    mDummy : BOOL;
    mFillerEstSlew : SlewLimit;
    mFillingHead_PID : FB41_PIDController;
END_VAR

_LD_BODY
_NETWORKS : 4
_NETWORK
_COMMENT
Patrón 1: ACTION call con ???
_END_COMMENT
_LD_ASSIGN
_EMPTY
_EXPRESSION
_POSITIV

ENABLELIST : 1
_ASSIGN
_FUNCTIONBLOCK
???
_BOX_EXPR : 0
_ENABLED
_EXPRESSION
_POSITIV
Test_Pattern_Program.Read_Analog
_OUTPUTS : 0
_EXPRESSION
_POSITIV
_OUTPUTS : 1
_OUTPUT
_POSITIV
_NO_SET
mDummy
ENABLELIST_END
_OUTPUTS : 0

_NETWORK
_COMMENT
Patrón 2: Function Block directo
_END_COMMENT
_LD_ASSIGN
_EMPTY
_EXPRESSION
_POSITIV

ENABLELIST : 1
_ASSIGN
_FUNCTIONBLOCK
mFillerEstSlew
_BOX_EXPR : 4
_ENABLED
_OPERAND
_EXPRESSION
_POSITIV
gInputValue
_OPERAND
_EXPRESSION
_POSITIV
gSlewMax
_OPERAND
_EXPRESSION
_POSITIV
gCycle
_EXPRESSION
_POSITIV
SlewLimit
_OUTPUTS : 1
_OUTPUT
_POSITIV
_NO_SET
mDummy
ENABLELIST_END
_OUTPUTS : 0

_NETWORK
_COMMENT
Patrón 3: Otra ACTION call con ???
_END_COMMENT
_LD_ASSIGN
_EMPTY
_EXPRESSION
_POSITIV

ENABLELIST : 1
_ASSIGN
_FUNCTIONBLOCK
???
_BOX_EXPR : 0
_ENABLED
_EXPRESSION
_POSITIV
Test_Pattern_Program.Calculations
_OUTPUTS : 0
_EXPRESSION
_POSITIV
_OUTPUTS : 1
_OUTPUT
_POSITIV
_NO_SET
mDummy
ENABLELIST_END
_OUTPUTS : 0

_NETWORK
_COMMENT
Patrón 4: Function Block PID directo
_END_COMMENT
_LD_ASSIGN
_EMPTY
_EXPRESSION
_POSITIV

ENABLELIST : 1
_ASSIGN
_FUNCTIONBLOCK
mFillingHead_PID
_BOX_EXPR : 20
_ENABLED
_OPERAND
_EXPRESSION
_POSITIV
gSetpoint
_OPERAND
_EXPRESSION
_POSITIV
gProcessValue
_EXPRESSION
_POSITIV
FB41_PIDController
_OUTPUTS : 1
_OUTPUT
_POSITIV
_NO_SET
mPIDOutput
ENABLELIST_END
_OUTPUTS : 0

END_PROGRAM

ACTION Read_Analog:
_LD_BODY
_NETWORKS : 1
_NETWORK
_COMMENT
ACTION de ejemplo
_END_COMMENT
_LD_ASSIGN
_LD_CONTACT
gAnalogEnable
_EXPRESSION
_POSITIV
_EXPRESSION
_POSITIV

ENABLELIST : 1
_ASSIGN
_FUNCTION
ReadAnalogIn
_OUTPUTS : 1
_OUTPUT
_POSITIV
_NO_SET
gAnalogValue
ENABLELIST_END
_OUTPUTS : 0
END_ACTION

ACTION Calculations:
gCalculatedValue := gInputA + gInputB * 2.5;
mDummy := TRUE;
END_ACTION
"""
    
    # Escribir archivo de prueba
    test_file = "test_pattern_example.exp"
    with open(test_file, 'w', encoding='utf-8') as f:
        f.write(test_content)
    
    print(f"✓ Archivo de prueba creado: {test_file}")
    print("-" * 60)
    
    # Crear convertidor
    converter = SimpleLadConverter()
    
    # Parsear archivo
    print("🔍 PARSEANDO ARCHIVO...")
    converter.parse_file(test_file)
    
    print(f"\n📊 RESUMEN:")
    print(f"  ✓ Programa: {converter.program_name}")
    print(f"  ✓ Redes encontradas: {len(converter.networks)}")
    print(f"  ✓ ACTIONs encontradas: {list(converter.actions.keys())}")
    
    # Analizar tipos de llamadas encontradas
    action_calls = []
    function_blocks = []
    
    print(f"\n📋 ANÁLISIS DETALLADO DE REDES:")
    for network in converter.networks:
        print(f"  Red {network['id']}: {network['comment']}")
        if network['logic']:
            logic_type = network['logic']['type']
            logic_name = network['logic'].get('name', 'Sin nombre')
            
            if logic_type == 'ACTION_CALL':
                action_calls.append(logic_name)
                print(f"    ✓ PATRÓN ???: ACTION call → {logic_name}")
            elif logic_type == 'FUNCTION_BLOCK':
                function_blocks.append(logic_name)
                print(f"    ✓ PATRÓN DIRECTO: Function Block → {logic_name}")
            else:
                print(f"    ℹ Otro tipo: {logic_type} → {logic_name}")
        else:
            print(f"    ⚠ Sin lógica detectada")
    
    print(f"\n🔍 LLAMADAS DETECTADAS:")
    print(f"  📞 ACTION calls (patrón ???): {len(action_calls)}")
    for call in action_calls:
        print(f"    • {call}")
    
    print(f"  🔧 Function Blocks (directos): {len(function_blocks)}")
    for fb in function_blocks:
        print(f"    • {fb}")
    
    # Generar código SCL para verificar
    print(f"\n📝 GENERANDO CÓDIGO SCL...")
    scl_code = converter.convert_to_structured()
    
    # Guardar archivo de prueba
    output_file = "test_pattern_output.scl"
    with open(output_file, 'w', encoding='utf-8') as f:
        f.write(scl_code)
    
    print(f"  ✓ Guardado en: {output_file}")
    
    # Mostrar sección relevante del código generado
    lines = scl_code.split('\n')
    print(f"\n📄 CÓDIGO SCL GENERADO (sección principal):")
    
    # Buscar sección principal
    main_start = -1
    main_end = -1
    for i, line in enumerate(lines):
        if "CÓDIGO PRINCIPAL" in line:
            main_start = i
        elif main_start > -1 and "END_PROGRAM" in line:
            main_end = i + 1
            break
    
    if main_start > -1:
        section_lines = lines[main_start:main_end] if main_end > -1 else lines[main_start:main_start+20]
        for i, line in enumerate(section_lines, main_start+1):
            print(f"  {i:2d}: {line}")
    
    # Limpiar archivos temporales
    try:
        os.remove(test_file)
        print(f"\n🧹 Archivo temporal eliminado: {test_file}")
    except:
        pass
    
    print(f"\n✅ CONCLUSIÓN:")
    print(f"   Tu observación es CORRECTA:")
    print(f"   • _FUNCTIONBLOCK + ??? = ACTION call")
    print(f"   • _FUNCTIONBLOCK + nombre_directo = Function Block")
    print(f"   • El parser ahora detecta ambos patrones correctamente!")

if __name__ == "__main__":
    test_pattern_detection() 