import psutil
import whatap.util.process_util as process_util
import whatap.util.logging_util as logging_util


class NicInfo:
    def __init__(self):
        self.nicName = ""
        self.ipAddress = ""
        self.macAddress = ""
        self.link = ""
        self.state = ""
        self.duplex = None
        self.speed = None
        self.mode = None
        self.windowsDriver = None


def GetNicInfoList():
    result = []
    try:
        import socket as _socket
        addrs = psutil.net_if_addrs()
        stats = {}
        try:
            stats = psutil.net_if_stats()
        except Exception:
            pass

        _AF_LINK = getattr(psutil, 'AF_LINK', None)

        for iface, addr_list in addrs.items():
            if iface == 'lo' or iface.startswith('lo'):
                continue

            info = NicInfo()
            info.nicName = iface

            ips = []
            for addr in addr_list:
                if addr.family == _socket.AF_INET:
                    ips.append(addr.address)
                elif _AF_LINK is not None and addr.family == _AF_LINK:
                    info.macAddress = addr.address
            info.ipAddress = ",".join(ips)

            # state / speed via psutil (kstat-based, no external command)
            if iface in stats:
                s = stats[iface]
                info.state = 'UP' if s.isup else 'DOWN'
                info.link = 'yes' if s.isup else 'no'
                if hasattr(s, 'speed') and s.speed and s.speed > 0:
                    info.speed = float(s.speed) * 1000000.0

            # MAC fallback via ifconfig if psutil AF_LINK not available
            if not info.macAddress:
                try:
                    ifconfig = process_util.executeCommandShellWithTimeout('ifconfig %s' % iface, timeout=5)
                    for line in ifconfig.split('\n'):
                        if 'ether' in line:
                            tokens = line.strip().split()
                            idx = tokens.index('ether') if 'ether' in tokens else -1
                            if idx >= 0 and idx + 1 < len(tokens):
                                info.macAddress = tokens[idx + 1]
                            break
                except Exception:
                    pass

            # duplex + state/speed fallback via dladm
            try:
                dladm = process_util.executeCommandShellWithTimeout('dladm show-phys -p -o LINK,STATE,DUPLEX,SPEED %s 2>/dev/null' % iface, timeout=10)
                for line in dladm.split('\n'):
                    line = line.strip()
                    if ':' in line:
                        parts = line.split(':')
                        if len(parts) >= 4:
                            if not info.state:
                                state_val = parts[1].strip().upper()
                                info.state = 'UP' if state_val == 'UP' else 'DOWN'
                                info.link = 'yes' if state_val == 'UP' else 'no'
                            duplex_val = parts[2].strip()
                            if duplex_val.lower() == 'full':
                                info.duplex = 'Full'
                            elif duplex_val.lower() == 'half':
                                info.duplex = 'Half'
                            elif duplex_val:
                                info.duplex = duplex_val
                            if info.speed is None:
                                speed_val = parts[3].strip()
                                if speed_val.isdigit() and int(speed_val) > 0:
                                    info.speed = float(speed_val) * 1000000.0
                        break
            except Exception:
                pass

            result.append(info)
    except Exception as e:
        logging_util.error('GetNicInfoList(Solaris) error:', e)
    return result
