import logging
from typing import Dict, List, Optional
import re

logger = logging.getLogger(__name__)

class HuaweiOLTManager:
    """Huawei OLT Manager (MA5608T, MA5800, etc.)"""
    
    def __init__(self, ssh_manager):
        self.ssh_manager = ssh_manager
    
    def get_onu_list(self, ip: str, username: str, password: str,
                     frame: int = 0, slot: int = 0, port: int = 0) -> List[Dict]:
        """Get ONU list on PON port"""
        try:
            command = f"display ont info {frame}/{slot} {port} all"
            output = self.ssh_manager.execute_command(
                ip, username, password, command, device_type='huawei'
            )
            
            onus = []
            lines = output.split('\n')
            
            for line in lines:
                if 'F/S/P' in line or '---' in line or not line.strip():
                    continue
                
                # Parse ONU info
                # Format: F/S/P   ONT-ID  Control  Run    Config   Match    Protect
                parts = line.split()
                if len(parts) >= 7:
                    try:
                        onus.append({
                            'fsp': parts[0],
                            'ont_id': int(parts[1]),
                            'control_flag': parts[2],
                            'run_state': parts[3],
                            'config_state': parts[4],
                            'match_state': parts[5],
                            'protect_side': parts[6] if len(parts) > 6 else 'N/A'
                        })
                    except:
                        continue
            
            return onus
            
        except Exception as e:
            logger.error(f"Failed to get ONU list: {e}")
            raise
    
    def get_onu_optical_info(self, ip: str, username: str, password: str,
                            frame: int = 0, slot: int = 0, port: int = 0,
                            ont_id: int = 0) -> Dict:
        """Get ONU optical power information"""
        try:
            command = f"display ont optical-info {frame}/{slot} {port} {ont_id}"
            output = self.ssh_manager.execute_command(
                ip, username, password, command, device_type='huawei'
            )
            
            optical_info = {
                'rx_power': None,
                'tx_power': None,
                'olt_rx_power': None,
                'temperature': None,
                'voltage': None,
                'bias_current': None,
            }
            
            # Parse optical info
            for line in output.split('\n'):
                if 'Rx optical power' in line:
                    match = re.search(r'([-\d.]+)', line)
                    if match:
                        optical_info['rx_power'] = float(match.group(1))
                elif 'Tx optical power' in line:
                    match = re.search(r'([-\d.]+)', line)
                    if match:
                        optical_info['tx_power'] = float(match.group(1))
                elif 'OLT Rx ONT optical power' in line or 'OLT RX power' in line:
                    match = re.search(r'([-\d.]+)', line)
                    if match:
                        optical_info['olt_rx_power'] = float(match.group(1))
                elif 'Temperature' in line:
                    match = re.search(r'([-\d.]+)', line)
                    if match:
                        optical_info['temperature'] = float(match.group(1))
                elif 'Voltage' in line:
                    match = re.search(r'([-\d.]+)', line)
                    if match:
                        optical_info['voltage'] = float(match.group(1))
                elif 'Bias current' in line:
                    match = re.search(r'([-\d.]+)', line)
                    if match:
                        optical_info['bias_current'] = float(match.group(1))
            
            return optical_info
            
        except Exception as e:
            logger.error(f"Failed to get optical info: {e}")
            raise
    
    def get_onu_version(self, ip: str, username: str, password: str,
                       frame: int = 0, slot: int = 0, port: int = 0,
                       ont_id: int = 0) -> Dict:
        """Get ONU version information"""
        try:
            command = f"display ont version {frame}/{slot} {port} {ont_id}"
            output = self.ssh_manager.execute_command(
                ip, username, password, command, device_type='huawei'
            )
            
            version_info = {
                'ont_id': ont_id,
                'equipment_id': None,
                'vendor_id': None,
                'ont_version': None,
                'product_id': None,
            }
            
            for line in output.split('\n'):
                if 'Equipment ID' in line:
                    parts = line.split(':')
                    if len(parts) > 1:
                        version_info['equipment_id'] = parts[1].strip()
                elif 'Vendor ID' in line:
                    parts = line.split(':')
                    if len(parts) > 1:
                        version_info['vendor_id'] = parts[1].strip()
                elif 'ONT version' in line or 'Software Version' in line:
                    parts = line.split(':')
                    if len(parts) > 1:
                        version_info['ont_version'] = parts[1].strip()
                elif 'Product ID' in line:
                    parts = line.split(':')
                    if len(parts) > 1:
                        version_info['product_id'] = parts[1].strip()
            
            return version_info
            
        except Exception as e:
            logger.error(f"Failed to get ONU version: {e}")
            raise
    
    def get_onu_distance(self, ip: str, username: str, password: str,
                        frame: int = 0, slot: int = 0, port: int = 0,
                        ont_id: int = 0) -> float:
        """Get ONU distance"""
        try:
            command = f"display ont info {frame}/{slot} {port} {ont_id}"
            output = self.ssh_manager.execute_command(
                ip, username, password, command, device_type='huawei'
            )
            
            for line in output.split('\n'):
                if 'Distance' in line:
                    match = re.search(r'(\d+)', line)
                    if match:
                        return int(match.group(1))
            
            return 0
            
        except Exception as e:
            logger.error(f"Failed to get ONU distance: {e}")
            return 0
    
    def add_onu(self, ip: str, username: str, password: str,
                frame: int, slot: int, port: int, ont_id: int,
                sn: str, profile_id: int = 1) -> str:
        """Add/Register ONU"""
        try:
            commands = [
                f"ont add {frame}/{slot} {port} {ont_id} sn-auth {sn} omci ont-lineprofile-id {profile_id} ont-srvprofile-id {profile_id}",
            ]
            
            output = self.ssh_manager.execute_config_commands(
                ip, username, password, commands, device_type='huawei'
            )
            
            return output
            
        except Exception as e:
            logger.error(f"Failed to add ONU: {e}")
            raise
    
    def delete_onu(self, ip: str, username: str, password: str,
                   frame: int, slot: int, port: int, ont_id: int) -> str:
        """Delete ONU"""
        try:
            commands = [
                f"ont delete {frame}/{slot} {port} {ont_id}",
            ]
            
            output = self.ssh_manager.execute_config_commands(
                ip, username, password, commands, device_type='huawei'
            )
            
            return output
            
        except Exception as e:
            logger.error(f"Failed to delete ONU: {e}")
            raise
    
    def reboot_onu(self, ip: str, username: str, password: str,
                   frame: int, slot: int, port: int, ont_id: int) -> str:
        """Reboot ONU"""
        try:
            command = f"ont reset {frame}/{slot} {port} {ont_id}"
            output = self.ssh_manager.execute_command(
                ip, username, password, command, device_type='huawei'
            )
            
            return output
            
        except Exception as e:
            logger.error(f"Failed to reboot ONU: {e}")
            raise
    
    def get_service_ports(self, ip: str, username: str, password: str,
                         frame: int = 0, slot: int = 0, port: int = 0) -> List[Dict]:
        """Get service port configuration"""
        try:
            command = f"display service-port port {frame}/{slot} {port}"
            output = self.ssh_manager.execute_command(
                ip, username, password, command, device_type='huawei'
            )
            
            service_ports = []
            lines = output.split('\n')
            
            for line in lines:
                if 'INDEX' in line or '---' in line or not line.strip():
                    continue
                
                parts = line.split()
                if len(parts) >= 8:
                    try:
                        service_ports.append({
                            'index': int(parts[0]),
                            'vport': parts[1],
                            'vlan_id': int(parts[2]) if parts[2].isdigit() else 0,
                            'port': parts[3],
                            'ont_id': parts[4],
                            'gem_port': parts[5],
                            'tx_traffic': parts[6],
                            'rx_traffic': parts[7],
                        })
                    except:
                        continue
            
            return service_ports
            
        except Exception as e:
            logger.error(f"Failed to get service ports: {e}")
            raise

# Note: This will use CiscoSSHManager with device_type='huawei' for SSH
# Netmiko supports Huawei devices
