#!/usr/bin/env python3

import os
import sys
from dataclasses import dataclass
from typing import List, Optional

@dataclass
class Dependency:
    name: str
    depType: str  # screen, input, sound, speech, core
    moduleName: str
    checkCommands: Optional[List[str]] = None  # Command-line tools to check
    pythonImports: Optional[List[str]] = None  # Python packages to check
    devicePaths: Optional[List[str]] = None    # Device files to check

def check_dependency(dep: Dependency) -> bool:
    """Check if a single dependency is satisfied."""
    isAvailable = True
    
    if dep.pythonImports:
        for package in dep.pythonImports:
            try:
                moduleName = package.split('.')[0]
                __import__(moduleName)
                print(f'{package}: OK')
            except ImportError:
                print(f'{package}: FAIL')
                isAvailable = False

    if dep.checkCommands:
        for cmd in dep.checkCommands:
            if os.path.exists(f'/usr/bin/{cmd}') or os.path.exists(f'/bin/{cmd}'):
                print(f'{cmd}: OK')
            else:
                print(f'{cmd}: FAIL')
                isAvailable = False

    if dep.devicePaths:
        for path in dep.devicePaths:
            if os.path.exists(path):
                print(f'{path}: OK')
            else:
                print(f'{path}: FAIL')
                isAvailable = False

    return isAvailable

# Define all dependencies
dependencyList = [
    # Core dependencies
    Dependency('FenrirCore', 'core', 'core', 
              pythonImports=[
                  'daemonize',
                  'enchant',
                  'pyperclip',
                  'setproctitle',
                  'xdg'
              ]),
    
    # Screen drivers
    Dependency('DummyScreen', 'screen', 'dummyDriver'),
    Dependency('VCSA', 'screen', 'vcsaDriver',
              pythonImports=['dbus'],
              devicePaths=['/dev/vcsa']),
    Dependency('PTY', 'screen', 'ptyDriver',
              pythonImports=['pyte']),
              
    # Input drivers
    Dependency('DummyInput', 'input', 'dummyDriver'),
    Dependency('DebugInput', 'input', 'debugDriver'),
    Dependency('Evdev', 'input', 'evdevDriver',
              pythonImports=['evdev', 'evdev.InputDevice', 'evdev.UInput', 'pyudev']),
    # Sound drivers
    Dependency('DummySound', 'sound', 'dummyDriver'),
    Dependency('DebugSound', 'sound', 'debugDriver'),
    Dependency('GenericSound', 'sound', 'genericDriver',
              checkCommands=['play', 'sox']),
    Dependency('GStreamer', 'sound', 'gstreamerDriver',
              pythonImports=['gi', 'gi.repository.GLib', 'gi.repository.Gst']),
              
    # Speech drivers
    Dependency('DummySpeech', 'speech', 'dummyDriver'),
    Dependency('DebugSpeech', 'speech', 'debugDriver'),
    Dependency('Speechd', 'speech', 'speechdDriver',
              pythonImports=['speechd']),
    Dependency('GenericSpeech', 'speech', 'genericDriver',
              checkCommands=['espeak-ng'])
]

defaultModules = {
    'FenrirCore',
    'VCSA',
    'Evdev',
    'GenericSpeech',
    'GenericSound'
}

def check_all_dependencies():
    print('Checking dependencies...\n')
    availableModules = []
    
    # Group dependencies by type for organized output
    for depType in ['core', 'screen', 'input', 'sound', 'speech']:
        print(f'{depType.upper()} DRIVERS')
        print('-' * 20)
        
        depsOfType = [d for d in dependencyList if d.depType == depType]
        for dep in depsOfType:
            print(f'\nChecking {dep.name}:')
            if check_dependency(dep):
                availableModules.append(dep.name)
        print('')

    print_summary(availableModules)

def print_summary(availableModules: List[str]):
    print('=' * 20)
    print('SUMMARY')
    print('=' * 20)
    
    missingModules = defaultModules - set(availableModules)
    if missingModules:
        print('Default Setup: FAIL')
        print('\nUnavailable Default Modules:')
        for module in missingModules:
            print(f'- {module}')
        print('\nYou may need to install the missing dependencies for the modules above or reconfigure fenrir to not use them.')
    else:
        print('Default Setup: OK')

    print('\nAvailable Modules:')
    for module in availableModules:
        print(f'- {module}')

if __name__ == '__main__':
    check_all_dependencies()
