from __future__ import annotations

import logging
import os
import shutil
from typing import Any

logger = logging.getLogger('intercept.dependencies')

# Additional paths to search for tools (e.g., /usr/sbin on Debian)
EXTRA_TOOL_PATHS = ['/usr/sbin', '/sbin']


def check_tool(name: str) -> bool:
    """Check if a tool is installed."""
    return get_tool_path(name) is not None


def get_tool_path(name: str) -> str | None:
    """Get the full path to a tool, checking standard PATH and extra locations."""
    # First check standard PATH
    path = shutil.which(name)
    if path:
        return path

    # Check additional paths (e.g., /usr/sbin for aircrack-ng on Debian)
    for extra_path in EXTRA_TOOL_PATHS:
        full_path = os.path.join(extra_path, name)
        if os.path.isfile(full_path) and os.access(full_path, os.X_OK):
            return full_path

    return None


# Comprehensive tool dependency definitions
TOOL_DEPENDENCIES = {
    'pager': {
        'name': 'Pager Decoding',
        'tools': {
            'rtl_fm': {
                'required': True,
                'description': 'RTL-SDR FM demodulator',
                'install': {
                    'apt': 'sudo apt install rtl-sdr',
                    'brew': 'brew install librtlsdr',
                    'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
                }
            },
            'multimon-ng': {
                'required': True,
                'description': 'Digital transmission decoder',
                'install': {
                    'apt': 'sudo apt install multimon-ng',
                    'brew': 'brew install multimon-ng',
                    'manual': 'https://github.com/EliasOenal/multimon-ng'
                }
            },
            'rtl_test': {
                'required': False,
                'description': 'RTL-SDR device detection',
                'install': {
                    'apt': 'sudo apt install rtl-sdr',
                    'brew': 'brew install librtlsdr',
                    'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
                }
            }
        }
    },
    'sensor': {
        'name': '433MHz Sensors',
        'tools': {
            'rtl_433': {
                'required': True,
                'description': 'ISM band decoder for sensors, weather stations, TPMS',
                'install': {
                    'apt': 'sudo apt install rtl-433',
                    'brew': 'brew install rtl_433',
                    'manual': 'https://github.com/merbanan/rtl_433'
                }
            }
        }
    },
    'wifi': {
        'name': 'WiFi Reconnaissance',
        'tools': {
            'airmon-ng': {
                'required': True,
                'description': 'Monitor mode controller',
                'install': {
                    'apt': 'sudo apt install aircrack-ng',
                    'brew': 'Not available on macOS',
                    'manual': 'https://aircrack-ng.org'
                }
            },
            'airodump-ng': {
                'required': True,
                'description': 'WiFi network scanner',
                'install': {
                    'apt': 'sudo apt install aircrack-ng',
                    'brew': 'Not available on macOS',
                    'manual': 'https://aircrack-ng.org'
                }
            },
            'aireplay-ng': {
                'required': False,
                'description': 'Deauthentication / packet injection',
                'install': {
                    'apt': 'sudo apt install aircrack-ng',
                    'brew': 'Not available on macOS',
                    'manual': 'https://aircrack-ng.org'
                }
            },
            'aircrack-ng': {
                'required': False,
                'description': 'Handshake verification',
                'install': {
                    'apt': 'sudo apt install aircrack-ng',
                    'brew': 'brew install aircrack-ng',
                    'manual': 'https://aircrack-ng.org'
                }
            },
            'hcxdumptool': {
                'required': False,
                'description': 'PMKID capture tool',
                'install': {
                    'apt': 'sudo apt install hcxdumptool',
                    'brew': 'brew install hcxtools',
                    'manual': 'https://github.com/ZerBea/hcxdumptool'
                }
            },
            'hcxpcapngtool': {
                'required': False,
                'description': 'PMKID hash extractor',
                'install': {
                    'apt': 'sudo apt install hcxtools',
                    'brew': 'brew install hcxtools',
                    'manual': 'https://github.com/ZerBea/hcxtools'
                }
            }
        }
    },
    'bluetooth': {
        'name': 'Bluetooth Scanning',
        'tools': {
            'hcitool': {
                'required': False,
                'description': 'Bluetooth HCI tool (legacy)',
                'install': {
                    'apt': 'sudo apt install bluez',
                    'brew': 'Not available on macOS (use native)',
                    'manual': 'http://www.bluez.org'
                }
            },
            'bluetoothctl': {
                'required': True,
                'description': 'Modern Bluetooth controller',
                'install': {
                    'apt': 'sudo apt install bluez',
                    'brew': 'Not available on macOS (use native)',
                    'manual': 'http://www.bluez.org'
                }
            },
            'hciconfig': {
                'required': False,
                'description': 'Bluetooth adapter configuration',
                'install': {
                    'apt': 'sudo apt install bluez',
                    'brew': 'Not available on macOS',
                    'manual': 'http://www.bluez.org'
                }
            }
        }
    },
    'aircraft': {
        'name': 'Aircraft Tracking (ADS-B)',
        'tools': {
            'dump1090': {
                'required': False,
                'description': 'Mode S / ADS-B decoder (preferred)',
                'install': {
                    'apt': 'sudo apt install dump1090-mutability (or build dump1090-fa from source)',
                    'brew': 'brew install dump1090-mutability',
                    'manual': 'https://github.com/flightaware/dump1090'
                },
                'alternatives': ['dump1090-mutability', 'dump1090-fa']
            },
            'rtl_adsb': {
                'required': False,
                'description': 'Simple ADS-B decoder',
                'install': {
                    'apt': 'sudo apt install rtl-sdr',
                    'brew': 'brew install librtlsdr',
                    'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
                }
            }
        }
    },
    'acars': {
        'name': 'Aircraft Messaging (ACARS)',
        'tools': {
            'acarsdec': {
                'required': True,
                'description': 'ACARS VHF decoder',
                'install': {
                    'apt': 'Run ./setup.sh (builds from source)',
                    'brew': 'Run ./setup.sh (builds from source)',
                    'manual': 'https://github.com/TLeconte/acarsdec'
                }
            }
        }
    },
    'aprs': {
        'name': 'APRS Tracking',
        'tools': {
            'direwolf': {
                'required': False,
                'description': 'APRS/packet radio decoder (preferred)',
                'install': {
                    'apt': 'sudo apt install direwolf',
                    'brew': 'brew install direwolf',
                    'manual': 'https://github.com/wb2osz/direwolf'
                }
            },
            'multimon-ng': {
                'required': False,
                'description': 'Alternative AFSK1200 decoder',
                'install': {
                    'apt': 'sudo apt install multimon-ng',
                    'brew': 'brew install multimon-ng',
                    'manual': 'https://github.com/EliasOenal/multimon-ng'
                }
            }
        }
    },
    'satellite': {
        'name': 'Satellite Tracking',
        'tools': {
            'skyfield': {
                'required': True,
                'description': 'Python orbital mechanics library',
                'install': {
                    'pip': 'pip install skyfield',
                    'manual': 'https://rhodesmill.org/skyfield/'
                },
                'python_module': True
            }
        }
    },
    'sdr_hardware': {
        'name': 'SDR Hardware Support',
        'tools': {
            'SoapySDRUtil': {
                'required': False,
                'description': 'Universal SDR abstraction (required for LimeSDR, HackRF)',
                'install': {
                    'apt': 'sudo apt install soapysdr-tools',
                    'brew': 'brew install soapysdr',
                    'manual': 'https://github.com/pothosware/SoapySDR'
                }
            },
            'rx_fm': {
                'required': False,
                'description': 'SoapySDR FM receiver (for non-RTL hardware)',
                'install': {
                    'manual': 'Part of SoapySDR utilities or build from source'
                }
            },
            'LimeUtil': {
                'required': False,
                'description': 'LimeSDR native utilities',
                'install': {
                    'apt': 'sudo apt install limesuite',
                    'brew': 'brew install limesuite',
                    'manual': 'https://github.com/myriadrf/LimeSuite'
                }
            },
            'SoapyLMS7': {
                'required': False,
                'description': 'SoapySDR plugin for LimeSDR',
                'install': {
                    'apt': 'sudo apt install soapysdr-module-lms7',
                    'brew': 'brew install soapylms7',
                    'manual': 'https://github.com/myriadrf/LimeSuite'
                }
            },
            'hackrf_info': {
                'required': False,
                'description': 'HackRF native utilities',
                'install': {
                    'apt': 'sudo apt install hackrf',
                    'brew': 'brew install hackrf',
                    'manual': 'https://github.com/greatscottgadgets/hackrf'
                }
            },
            'SoapyHackRF': {
                'required': False,
                'description': 'SoapySDR plugin for HackRF',
                'install': {
                    'apt': 'sudo apt install soapysdr-module-hackrf',
                    'brew': 'brew install soapyhackrf',
                    'manual': 'https://github.com/pothosware/SoapyHackRF'
                }
            },
            'readsb': {
                'required': False,
                'description': 'ADS-B decoder with SoapySDR support',
                'install': {
                    'apt': 'Build from source with SoapySDR support',
                    'brew': 'Build from source with SoapySDR support',
                    'manual': 'https://github.com/wiedehopf/readsb'
                }
            }
        }
    },
    'tscm': {
        'name': 'TSCM Counter-Surveillance',
        'tools': {
            'rtl_power': {
                'required': False,
                'description': 'Wideband spectrum sweep for RF analysis',
                'install': {
                    'apt': 'sudo apt install rtl-sdr',
                    'brew': 'brew install librtlsdr',
                    'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
                }
            },
            'rtl_fm': {
                'required': True,
                'description': 'RF signal demodulation',
                'install': {
                    'apt': 'sudo apt install rtl-sdr',
                    'brew': 'brew install librtlsdr',
                    'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
                }
            },
            'rtl_433': {
                'required': False,
                'description': 'ISM band device decoding',
                'install': {
                    'apt': 'sudo apt install rtl-433',
                    'brew': 'brew install rtl_433',
                    'manual': 'https://github.com/merbanan/rtl_433'
                }
            },
            'airmon-ng': {
                'required': False,
                'description': 'WiFi monitor mode for network scanning',
                'install': {
                    'apt': 'sudo apt install aircrack-ng',
                    'brew': 'Not available on macOS',
                    'manual': 'https://aircrack-ng.org'
                }
            },
            'bluetoothctl': {
                'required': False,
                'description': 'Bluetooth device scanning',
                'install': {
                    'apt': 'sudo apt install bluez',
                    'brew': 'Not available on macOS (use native)',
                    'manual': 'http://www.bluez.org'
                }
            }
        }
    }
}


def check_all_dependencies() -> dict[str, dict[str, Any]]:
    """Check all tool dependencies and return status."""
    results: dict[str, dict[str, Any]] = {}

    for mode, config in TOOL_DEPENDENCIES.items():
        mode_result = {
            'name': config['name'],
            'tools': {},
            'ready': True,
            'missing_required': []
        }

        for tool, tool_config in config['tools'].items():
            # Check if it's a Python module
            if tool_config.get('python_module'):
                try:
                    __import__(tool)
                    installed = True
                except Exception as e:
                    logger.debug(f"Failed to import {tool}: {type(e).__name__}: {e}")
                    installed = False
            else:
                # Check for alternatives
                alternatives = tool_config.get('alternatives', [])
                installed = check_tool(tool) or any(check_tool(alt) for alt in alternatives)

            mode_result['tools'][tool] = {
                'installed': installed,
                'required': tool_config['required'],
                'description': tool_config['description'],
                'install': tool_config['install']
            }

            if tool_config['required'] and not installed:
                mode_result['ready'] = False
                mode_result['missing_required'].append(tool)

        results[mode] = mode_result

    return results
