#!/usr/bin/env python3
# 04_generate_pjsip_conf.py
# Generar configuración PJSIP para todas las extensiones

import csv
import mysql.connector
from datetime import datetime

def generate_pjsip_config():
    """Generar archivo de configuración PJSIP"""
    
    # Conectar a BD para obtener extensiones
    conn = mysql.connector.connect(
        host='localhost',
        user='asteriskuser',
        password='coolla007llama09',
        database='asterisk'
    )
    cursor = conn.cursor(dictionary=True)
    
    # Archivo de salida
    output_file = '/etc/asterisk/pjsip_new_extensions.conf'
    
    with open(output_file, 'w') as f:
        # Escribir encabezado y templates
        f.write(f""";
; Configuración PJSIP - Nueva Estructura de Extensiones
; Generado: {datetime.now()}
; Total extensiones: Ver conteo al final
;

; ==========================================
; TEMPLATES
; ==========================================

[transport-tcp]
type=transport
protocol=tcp
bind=0.0.0.0:5060
local_net=192.168.0.0/16
local_net=10.0.0.0/8
local_net=172.16.0.0/12

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
local_net=192.168.0.0/16
local_net=10.0.0.0/8
local_net=172.16.0.0/12

; Template base para endpoints
[endpoint-template](!)
type=endpoint
transport=transport-udp
context=from-internal
disallow=all
allow=alaw
allow=ulaw
allow=gsm
direct_media=no
trust_id_outbound=yes
device_state_busy_at=1
dtmf_mode=rfc4733
language=es
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes

; Template para autenticación
[auth-template](!)
type=auth
auth_type=userpass

; Template para AOR
[aor-template](!)
type=aor
max_contacts=2
qualify_frequency=30
authenticate_qualify=yes
minimum_expiration=60
default_expiration=3600

; ==========================================
; EXTENSIONES POR TIPO
; ==========================================

""")
        
        # Obtener todas las extensiones activas
        sql = """
        SELECT extension, tipo, nombre, password, telefono_conexion, grupo
        FROM extensiones_sistema
        WHERE activo = 1
        ORDER BY tipo, extension
        """
        cursor.execute(sql)
        extensions = cursor.fetchall()
        
        current_type = None
        type_count = {}
        
        for ext in extensions:
            # Escribir separador por tipo
            if ext['tipo'] != current_type:
                current_type = ext['tipo']
                type_count[current_type] = 0
                f.write(f"\n; ==========================================\n")
                f.write(f"; {current_type}\n")
                f.write(f"; ==========================================\n\n")
            
            type_count[current_type] += 1
            
            # Determinar contexto según tipo
            context_map = {
                'COORDINADOR': 'coordinators-context',
                'TAROT': 'agents-context',
                'INFO': 'info-context',
                'USUARIO': 'user-functions',
                'RESCATE': 'rescue-context',
                'CALL_CENTER_EXTERNO': 'external-cc'
            }
            context = context_map.get(ext['tipo'], 'from-internal')
            
            # Configuración específica por tipo
            max_contacts = 4 if ext['tipo'] == 'COORDINADOR' else 2
            qualify_frequency = 20 if ext['tipo'] == 'COORDINADOR' else 30
            
            # Escribir configuración
            f.write(f"; {ext['nombre']}")
            if ext['grupo']:
                f.write(f" ({ext['grupo']})")
            if ext['telefono_conexion'] and ext['telefono_conexion'] != 'CENTRALITA':
                f.write(f" - Tel: {ext['telefono_conexion']}")
            f.write(f"\n")
            
            f.write(f"[{ext['extension']}](endpoint-template)\n")
            f.write(f"auth = {ext['extension']}\n")
            f.write(f"aors = {ext['extension']}\n")
            f.write(f"callerid = \"{ext['nombre']}\" <{ext['extension']}>\n")
            f.write(f"context = {context}\n")
            
            # Configuraciones especiales
            if ext['tipo'] == 'COORDINADOR':
                f.write("call_group = 1\n")
                f.write("pickup_group = 1\n")
            elif ext['tipo'] == 'TAROT':
                f.write("call_group = 2\n")
                f.write("pickup_group = 2\n")
            elif ext['tipo'] == 'INFO':
                f.write("call_group = 3\n")
                f.write("pickup_group = 3\n")
            
            f.write(f"\n")
            
            f.write(f"[{ext['extension']}](auth-template)\n")
            f.write(f"password = {ext['password']}\n")
            f.write(f"username = {ext['extension']}\n")
            f.write(f"\n")
            
            f.write(f"[{ext['extension']}](aor-template)\n")
            if ext['tipo'] == 'COORDINADOR':
                f.write(f"max_contacts = {max_contacts}\n")
            f.write(f"qualify_frequency = {qualify_frequency}\n")
            f.write(f"\n")
        
        # Escribir resumen
        f.write("\n; ==========================================\n")
        f.write("; RESUMEN\n")
        f.write("; ==========================================\n")
        f.write(f"; Total extensiones: {len(extensions)}\n")
        for tipo, count in type_count.items():
            f.write(f"; {tipo}: {count}\n")
        f.write(f"; Generado: {datetime.now()}\n")
        
    cursor.close()
    conn.close()
    
    print(f"Configuración PJSIP generada en: {output_file}")
    print("\nResumen:")
    for tipo, count in type_count.items():
        print(f"  {tipo}: {count}")
    print(f"  TOTAL: {len(extensions)}")
    
    # Verificar sintaxis
    print("\nVerificando sintaxis...")
    import subprocess
    result = subprocess.run(['asterisk', '-rx', 'pjsip show version'], 
                          capture_output=True, text=True)
    if result.returncode == 0:
        print("✓ Asterisk PJSIP disponible")
    else:
        print("✗ Error verificando PJSIP")
    
    return output_file

def create_pjsip_wizard_config():
    """Crear configuración alternativa usando PJSIP wizard (más simple)"""
    
    output_file = '/etc/asterisk/pjsip_wizard_new.conf'
    
    conn = mysql.connector.connect(
        host='localhost',
        user='asteriskuser',
        password='coolla007llama09',
        database='asterisk'
    )
    cursor = conn.cursor(dictionary=True)
    
    with open(output_file, 'w') as f:
        f.write(f""";
; Configuración PJSIP usando Wizard
; Generado: {datetime.now()}
;

[user-defaults](!)
type = wizard
accepts_registrations = yes
accepts_auth = yes
endpoint/context = from-internal
endpoint/disallow = all
endpoint/allow = alaw
endpoint/allow = ulaw
endpoint/dtmf_mode = rfc4733
endpoint/language = es
endpoint/rtp_symmetric = yes
endpoint/force_rport = yes
endpoint/direct_media = no
endpoint/trust_id_outbound = yes
endpoint/device_state_busy_at = 1
aor/max_contacts = 2
aor/qualify_frequency = 30
aor/authenticate_qualify = yes

""")
        
        # Obtener extensiones
        cursor.execute("""
            SELECT extension, tipo, nombre, password, grupo
            FROM extensiones_sistema
            WHERE activo = 1
            ORDER BY tipo, extension
        """)
        
        current_type = None
        
        for ext in cursor.fetchall():
            if ext['tipo'] != current_type:
                current_type = ext['tipo']
                f.write(f"\n; === {current_type} ===\n\n")
            
            # Contexto según tipo
            context_map = {
                'COORDINADOR': 'coordinators-context',
                'TAROT': 'agents-context',
                'INFO': 'info-context',
                'USUARIO': 'user-functions',
                'RESCATE': 'rescue-context',
                'CALL_CENTER_EXTERNO': 'external-cc'
            }
            context = context_map.get(ext['tipo'], 'from-internal')
            
            f.write(f"; {ext['nombre']}\n")
            f.write(f"[{ext['extension']}](user-defaults)\n")
            f.write(f"inbound_auth/username = {ext['extension']}\n")
            f.write(f"inbound_auth/password = {ext['password']}\n")
            f.write(f"endpoint/context = {context}\n")
            f.write(f"endpoint/callerid = \"{ext['nombre']}\" <{ext['extension']}>\n")
            
            if ext['tipo'] == 'COORDINADOR':
                f.write("aor/max_contacts = 4\n")
                f.write("endpoint/call_group = 1\n")
                f.write("endpoint/pickup_group = 1\n")
            
            f.write("\n")
    
    cursor.close()
    conn.close()
    
    print(f"\nConfiguración Wizard generada en: {output_file}")
    return output_file

if __name__ == "__main__":
    print("=== GENERADOR DE CONFIGURACIÓN PJSIP ===")
    print("")
    
    # Generar ambas versiones
    config_file = generate_pjsip_config()
    wizard_file = create_pjsip_wizard_config()
    
    print("\n✓ Configuración generada exitosamente")
    print("\nPara activar:")
    print(f"1. Revisar: {config_file}")
    print(f"2. O usar wizard: {wizard_file}")
    print("3. Incluir en pjsip.conf: #include pjsip_new_extensions.conf")
    print("4. Recargar: asterisk -rx 'pjsip reload'")
    print("")