"""
RRM Features Module (802.11k/v/r)
Detects Radio Resource Management features for optimized roaming
"""

from scapy.all import *
from scapy.layers.dot11 import *


def detect_rrm_features(packets):
    """Detect 802.11k/v/r (Radio Resource Management) features"""
    rrm = {
        '802.11k': {'detected': False, 'neighbor_reports': 0, 'beacon_reports': 0, 'details': []},
        '802.11v': {'detected': False, 'bss_transition': 0, 'details': []},
        '802.11r': {'detected': False, 'ft_auth': 0, 'ft_action': 0, 'details': []},
        'client_steering': {'detected': False, 'events': []},
        'load_balancing': {'detected': False, 'band_steering': 0},
        'not_detected_reason': {}
    }

    for idx, pkt in enumerate(packets, 1):
        try:
            if pkt.haslayer(Dot11):
                dot11 = pkt[Dot11]

                # 802.11k detection (Action frames, category 5 = Radio Measurement)
                if dot11.type == 0 and dot11.subtype == 0x0d:  # Action frame
                    if hasattr(pkt, 'load') and len(pkt.load) >= 2:
                        category = pkt.load[0]
                        if category == 5:  # Radio Measurement
                            action = pkt.load[1]
                            if action == 1:  # Neighbor Report Request/Response
                                rrm['802.11k']['detected'] = True
                                rrm['802.11k']['neighbor_reports'] += 1
                                if len(rrm['802.11k']['details']) < 3:
                                    rrm['802.11k']['details'].append({'packet': idx, 'type': 'Neighbor Report'})
                            elif action == 5:  # Beacon Report
                                rrm['802.11k']['detected'] = True
                                rrm['802.11k']['beacon_reports'] += 1
                                if len(rrm['802.11k']['details']) < 3:
                                    rrm['802.11k']['details'].append({'packet': idx, 'type': 'Beacon Report'})

            # 802.11k from IEs (RRM Enabled Capabilities)
            if pkt.haslayer(Dot11Beacon) or pkt.haslayer(Dot11ProbeResp) or pkt.haslayer(Dot11AssoReq):
                if pkt.haslayer(Dot11Elt):
                    elt = pkt[Dot11Elt]
                    while elt:
                        # RRM Enabled Capabilities IE (ID 70)
                        if elt.ID == 70:
                            rrm['802.11k']['detected'] = True
                            if len(rrm['802.11k']['details']) < 5:
                                rrm['802.11k']['details'].append({
                                    'packet': idx,
                                    'type': 'RRM Enabled Capabilities IE'
                                })

                        # BSS Transition Management (802.11v) - Vendor Specific or Extended Capabilities
                        if elt.ID == 127 and len(elt.info) >= 3:  # Extended Capabilities
                            # Byte 2, bit 3: BSS Transition
                            if len(elt.info) >= 3 and (elt.info[2] & 0x08):
                                rrm['802.11v']['detected'] = True
                                rrm['802.11v']['bss_transition'] += 1
                                if len(rrm['802.11v']['details']) < 3:
                                    rrm['802.11v']['details'].append({
                                        'packet': idx,
                                        'type': 'BSS Transition Supported'
                                    })

                        # Mobility Domain IE (802.11r Fast Transition)
                        if elt.ID == 54:  # Mobility Domain
                            rrm['802.11r']['detected'] = True
                            if len(rrm['802.11r']['details']) < 3:
                                rrm['802.11r']['details'].append({
                                    'packet': idx,
                                    'type': 'Mobility Domain IE'
                                })

                        # Fast Transition IE (ID 55)
                        if elt.ID == 55:
                            rrm['802.11r']['detected'] = True
                            rrm['802.11r']['ft_action'] += 1
                            if len(rrm['802.11r']['details']) < 3:
                                rrm['802.11r']['details'].append({
                                    'packet': idx,
                                    'type': 'Fast Transition IE'
                                })

                        if hasattr(elt, 'payload'):
                            elt = elt.payload.getlayer(Dot11Elt)
                        else:
                            break

            # 802.11r FT Authentication (subtype 0x0b - Authentication)
            if pkt.haslayer(Dot11Auth):
                # FT Authentication uses algorithm 2
                auth = pkt[Dot11Auth]
                if hasattr(auth, 'algo') and auth.algo == 2:
                    rrm['802.11r']['detected'] = True
                    rrm['802.11r']['ft_auth'] += 1

            # 802.11v BSS Transition Management frame detection
            if pkt.haslayer(Dot11) and dot11.type == 0 and dot11.subtype == 0x0d:
                if hasattr(pkt, 'load') and len(pkt.load) >= 2:
                    category = pkt.load[0]
                    if category == 10:  # WNM (Wireless Network Management) for 802.11v
                        rrm['802.11v']['detected'] = True
                        rrm['802.11v']['bss_transition'] += 1
                        rrm['client_steering']['detected'] = True
                        if len(rrm['client_steering']['events']) < 5:
                            rrm['client_steering']['events'].append({
                                'packet': idx,
                                'type': '802.11v BSS Transition'
                            })

        except Exception:
            continue

    # Add explanations
    if not rrm['802.11k']['detected']:
        rrm['not_detected_reason']['802.11k'] = (
            "No 802.11k (Radio Resource Management) detected. "
            "Requires RRM Enabled Capabilities IE (ID 70) or Radio Measurement action frames (category 5). "
            "802.11k helps clients make better roaming decisions with neighbor reports."
        )

    if not rrm['802.11v']['detected']:
        rrm['not_detected_reason']['802.11v'] = (
            "No 802.11v (BSS Transition Management) detected. "
            "Requires Extended Capabilities IE with BSS Transition bit or WNM action frames (category 10). "
            "802.11v enables AP-assisted client steering for optimal roaming."
        )

    if not rrm['802.11r']['detected']:
        rrm['not_detected_reason']['802.11r'] = (
            "No 802.11r (Fast Transition) detected. "
            "Requires Mobility Domain IE (ID 54), FT IE (ID 55), or FT Authentication (algo 2). "
            "802.11r enables fast roaming with <50ms transitions for voice/video."
        )

    return rrm
