# -*- coding: utf-8 -*-
import subprocess, re, mysql.connector, sys, os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DB_PHP_PATH = '/var/www/html/db.php'

import os
import os
import os
import os
def __get_db_config_dynamic():
    cfg = {'host': '127.0.0.1', 'user': 'saas_admin', 'password': 'AdminSaaS2026!', 'database': 'adminolt_db'}
    for db_path in ['/var/www/html/db.php', '/root/Workspace360_paquete/db.php']:
        try:
            if os.path.exists(db_path):
                with open(db_path, 'r', encoding='utf-8', errors='ignore') as f:
                    for line in f:
                        line = line.strip()
                        if line.startswith('$host') and '=' in line:
                            part = line.split("'")[1] if "'" in line else line.split('"')[1]
                            cfg['host'] = '127.0.0.1' if part == 'localhost' else part
                        elif line.startswith('$user') and '=' in line:
                            cfg['user'] = line.split("'")[1] if "'" in line else line.split('"')[1]
                        elif line.startswith('$pass') and '=' in line:
                            cfg['password'] = line.split("'")[1] if "'" in line else line.split('"')[1]
                        elif line.startswith('$db') and '=' in line:
                            cfg['database'] = line.split("'")[1] if "'" in line else line.split('"')[1]
                break
        except: pass
    return cfg
DB_CONFIG = __get_db_config_dynamic()
    conn = mysql.connector.connect(**db_config)
    cursor = conn.cursor()
    
    # =========================================================================
    # AUTO-REPARACIN DE MYSQL: Destruye el candado defectuoso
    # =========================================================================
    try:
        cursor.execute("ALTER TABLE naps DROP INDEX unique_port")
        conn.commit()
        print(" [INFO BD] Regla defectuosa 'unique_port' eliminada con exito.")
    except: pass
    try:
        # Crea la regla correcta: OLT + Frame + Slot + Puerto
        cursor.execute("ALTER TABLE naps ADD UNIQUE INDEX unique_olt_fsp (olt_id, frame, slot, port)")
        conn.commit()
    except: pass

    cursor.execute("SELECT id, nombre, ip_address, snmp_port, snmp_community FROM olts WHERE id = %s", (target_olt,))
    olt = cursor.fetchone()
    if not olt:
        print("OLT no encontrada.")
        sys.exit(1)
        
    olt_id, olt_name, olt_ip, olt_port, olt_comm = olt
    if not olt_port: olt_port = 161
    
    print(f"--- Descubrimiento Seguro de Tarjetas: {olt_name} ---")
    
    l_pn = get_snmp_walk_str(olt_ip, olt_port, olt_comm, "1.3.6.1.2.1.31.1.1.1.1")
    l_pd = get_snmp_walk_str(olt_ip, olt_port, olt_comm, "1.3.6.1.4.1.2011.6.128.1.1.2.21.1.6")
    
    if not l_pn and not l_pd:
        print(" [ERROR] No hay respuesta de la OLT. Verifica la conexion.")
        sys.exit(1)
        
    tech_names, desc_names, info_puertos = {}, {}, {}
    
    for l in l_pn:
        m = re.search(r'\.31\.1\.1\.1\.1\.(\d+)\s*=\s*STRING:\s*(.*)', l)
        if m:
            val = clean_string(m.group(2))
            m_fsp = re.search(r'(GPON|EPON|XG-PON|XGS-PON)[^\d]*(\d+)/(\d+)/(\d+)', val)
            if m_fsp:
                f, s, p = int(m_fsp.group(2)), int(m_fsp.group(3)), int(m_fsp.group(4))
                tech_names[(f, s, p)] = val
                
    for l in l_pd:
        m = re.search(r'\.21\.1\.6\.(\d+)\s*=\s*STRING:\s*(.*)', l)
        if m:
            val = clean_string(m.group(2))
            if val: 
                s, p = decode_huawei_index(int(m.group(1)))
                desc_names[(0, s, p)] = val
                
    for k, v_desc in desc_names.items():
        if k not in tech_names: tech_names[k] = f"GPON {k[0]}/{k[1]}/{k[2]}"
        info_puertos[k] = v_desc
        
    for k, v_tech in tech_names.items(): 
        if k not in info_puertos: info_puertos[k] = v_tech

    cursor.execute("SELECT id, frame, slot, port FROM naps WHERE olt_id = %s", (olt_id,))
    naps_existentes = {}
    for r in cursor.fetchall():
        try: naps_existentes[(int(r[1]), int(r[2]), int(r[3]))] = r[0]
        except: pass

    inserts_ok = 0
    updates_ok = 0
    errores_mysql = []

    for (f, s, p), nombre_nap in info_puertos.items():
        if (f, s, p) in naps_existentes:
            nap_id = naps_existentes[(f, s, p)]
            try:
                cursor.execute("UPDATE naps SET alias_nombre = %s WHERE id = %s AND (alias_nombre LIKE 'GPON%%' OR alias_nombre LIKE 'Puerto%%')", (nombre_nap, nap_id))
                updates_ok += 1
            except mysql.connector.Error as err:
                errores_mysql.append(f"Update {f}/{s}/{p}: {err.msg}")
        else:
            try:
                cursor.execute("INSERT INTO naps (olt_id, frame, slot, port, alias_nombre) VALUES (%s, %s, %s, %s, %s)", (olt_id, f, s, p, nombre_nap))
                inserts_ok += 1
            except mysql.connector.Error as err:
                errores_mysql.append(f"Insert {f}/{s}/{p}: {err.msg}")

    conn.commit()
    print(f" [OK] {len(info_puertos)} Puertos procesados: {inserts_ok} Nuevos agregados, {updates_ok} actualizados.")
    
    if errores_mysql:
        print(f" [ATENCION] Hubo {len(errores_mysql)} bloqueos de Base de Datos. ltimo error: {errores_mysql[-1]}")
        
    cursor.close()
    conn.close()

if __name__ == "__main__":
    main()