# -*- coding: utf-8 -*-
import mysql.connector
from netmiko import ConnectHandler
import sys

# --- CONFIGURACION DEV ---
import re, os
import re, os
import os
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()

def get_olts():
    conn = mysql.connector.connect(**DB_CONFIG)
    cursor = conn.cursor(dictionary=True)
    cursor.execute("SELECT id, nombre, ip_address, ssh_user, ssh_pass, ssh_port FROM olts")
    olts = cursor.fetchall()
    conn.close()
    return olts

def parse_and_sync(cursor, olt_id, output, type_prof):
    lines = output.splitlines()
    valid_profiles = []
    
    # 1. Analizamos la salida de la OLT y la guardamos en memoria
    for line in lines:
        line = line.strip()
        if not line or not line[0].isdigit(): continue
        parts = line.split()
        
        if type_prof in ('line', 'service'):
            if len(parts) >= 3 and parts[0].isdigit() and parts[-1].isdigit():
                pid = int(parts[0])
                pname = " ".join(parts[1:-1]).strip()
                valid_profiles.append((pid, pname))
                
        elif type_prof == 'speed':
            if len(parts) >= 4 and parts[0].isdigit():
                try:
                    pid = int(parts[0])
                    cir = int(parts[1]) if parts[1].isdigit() else 0
                    pir = int(parts[3]) if parts[3].isdigit() else 0
                    
                    if cir >= 1024 or pir >= 1024:
                        name_gen = f"Plan {round(cir/1024)}M/{round(pir/1024)}M"
                    else:
                        name_gen = f"Plan {cir}k/{pir}k"
                        
                    valid_profiles.append((pid, name_gen, cir, pir))
                except ValueError:
                    pass
    
    # 2. MODO WIPE & REPLACE: Borramos la tabla vieja corrupta y escribimos la lista limpia
    if type_prof == 'line':
        cursor.execute("DELETE FROM profiles_line WHERE olt_id=%s", (olt_id,))
        for p in valid_profiles:
            cursor.execute("INSERT INTO profiles_line (olt_id, profile_id, profile_name, activo) VALUES (%s, %s, %s, 1)", (olt_id, p[0], p[1]))
            
    elif type_prof == 'service':
        cursor.execute("DELETE FROM profiles_service WHERE olt_id=%s", (olt_id,))
        for p in valid_profiles:
            cursor.execute("INSERT INTO profiles_service (olt_id, profile_id, profile_name, activo) VALUES (%s, %s, %s, 1)", (olt_id, p[0], p[1]))
            
    elif type_prof == 'speed':
        cursor.execute("DELETE FROM profiles_speed WHERE olt_id=%s", (olt_id,))
        for p in valid_profiles:
            cursor.execute("INSERT INTO profiles_speed (olt_id, traffic_id, name, cir_kbps, pir_kbps, activo) VALUES (%s, %s, %s, %s, %s, 1)", (olt_id, p[0], p[1], p[2], p[3]))
            
    return len(valid_profiles)

def process_olt(olt_data):
    print(f"--- Sincronizando Perfiles: {olt_data['nombre']} ---")
    
    device = {
        'device_type': 'huawei_smartax',
        'host': olt_data['ip_address'],
        'username': olt_data['ssh_user'],
        'password': olt_data['ssh_pass'],
        'port': olt_data['ssh_port'],
        'global_delay_factor': 2
    }
    
    try:
        conn = ConnectHandler(**device)
        try: conn.enable()
        except: pass
        
        conn.send_command_timing("scroll 512")
        
        print(" > Obteniendo Line Profiles...")
        out_line = conn.send_command("display ont-lineprofile gpon all")
        
        print(" > Obteniendo Service Profiles...")
        out_srv = conn.send_command("display ont-srvprofile gpon all")
        
        print(" > Obteniendo Traffic Tables...")
        out_speed = conn.send_command("display traffic table ip from-index 0")
        
        conn.disconnect()
        
        # --- CONEXIN NICA A LA BASE DE DATOS ---
        db = mysql.connector.connect(**DB_CONFIG)
        cursor = db.cursor()
        
        c_line = parse_and_sync(cursor, olt_data['id'], out_line, 'line')
        c_srv = parse_and_sync(cursor, olt_data['id'], out_srv, 'service')
        c_speed = parse_and_sync(cursor, olt_data['id'], out_speed, 'speed')
        
        db.commit() # Sellamos la transaccin completa
        db.close()
        
        print(f" [OK] Base de datos purgada y actualizada -> Line: {c_line}, Srv: {c_srv}, Speed: {c_speed}")
            
    except Exception as e:
        print(f" [ERROR CRTICO] {e}")

if __name__ == "__main__":
    olts = get_olts()
    for o in olts:
        process_olt(o)
