from ..config import ConfigUnit
from .types import LinuxBoardType
from typing import Optional


class ServicesListConfig(ConfigUnit):
    NAME = 'services_list'

    @classmethod
    def schema(cls) -> Optional[dict]:
        return {
            'type': 'dict',
            'schema': {
                'system': dict(type='boolean'),
                'exec': dict(type='string'),
                'root': dict(type='boolean'),
                'after': dict(type='string'),
                'cron': {
                    'type': 'dict',
                    'schema': {
                        'time': dict(type='string', required=True),
                        'exec': dict(type='string', required=True),
                        'args': dict(type='string'),
                    }
                }
            }
        }

    @classmethod
    def validate(self):
        pass


class LinuxBoardsConfig(ConfigUnit):
    NAME = 'linux_boards'

    @classmethod
    def schema(cls) -> Optional[dict]:
        services_list = list(ServicesListConfig().keys())
        return {
            'type': 'dict',
            'schema': {
                'board': {
                    'type': 'string',
                    'required': True,
                    'allowed': [t.value for t in LinuxBoardType]
                },
                'role': {'type': 'string', 'required': False},
                'location': {'type': 'string', 'required': True},
                'notes': {'type': 'string', 'required': False},

                'network': {
                    'type': 'dict',
                    'schema': {
                        'ethernet': cls._network_device_schema(),
                        'wifi': cls._network_device_schema(),
                    }
                },
                'online': {'type': 'boolean', 'required': False},

                'services': {
                    'type': 'list',
                    'schema': {
                        'oneof': [
                            {'type': 'string', 'allowed': services_list},
                            {
                                'type': 'dict',
                                'schema': {
                                    'keyschema': {
                                        'type': 'string',
                                        'allowed': services_list
                                    }
                                },
                                'allow_unknown': True
                            }
                        ]

                    }
                },

                'ext_hdd': {
                    'type': 'list',
                    'schema': {
                        'type': 'dict',
                        'schema': {
                            'mountpoint': {'type': 'string', 'required': True},
                            'size': {'type': 'integer', 'required': True},
                            'uuid': {
                                'type': 'string',
                                'regex': '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$',
                                'required': True
                            },
                            'ssd': {'required': False, 'type': 'boolean'}
                        }
                    },
                }
            }
        }

    @classmethod
    def _network_device_schema(cls, required=False) -> dict:
        return {
            'type': 'list',
            'required': required,
            'schema': {
                'type': 'dict',
                'schema': {
                    'mac': cls._addr_schema(mac=True, required=True),
                    'mac_fake': {'type': 'boolean', 'required': False},
                    'ip': cls._addr_schema(only_ip=True, required=True),
                    'usb': {'type': 'boolean', 'required': False}
                }
            }
        }

    def get_board_disks(self, name: str) -> list[dict]:
        return self[name]['ext_hdd']

    def get_board_disks_count(self, name: str) -> int:
        return len(self[name]['ext_hdd'])
