#!/usr/bin/python3
import argparse
import configparser
from dataclasses import dataclass, field
from pathlib import Path

from syslog_ng_mod_astra.config.mod_astra_events_loader import ModAstraEventsLoader, load_json

NOTIFY_RC_DIR_PATH = Path('/usr/share/knotifications5')


@dataclass
class AstraEvent:
    id: str
    name_ru: str
    name_en: str


@dataclass
class AstraEventGroup:
    id: str
    name_ru: str
    name_en: str
    events: list[AstraEvent] = field(default_factory=list)


astra_events: list[AstraEventGroup] = []

special_groups = {
    'custom-events': AstraEventGroup('custom-events',
                                     'Пользовательские события',
                                     'Custom events')
}

missing_events_by_group = {
    'self-diagnostics': [AstraEvent('self_diagnostics',
                                   'Самодиагностика подсистемы регистрации событий',
                                   'Self-diagnostics of the event registration subsystem')]
}


def create_argument_parser():
    parser = argparse.ArgumentParser(
        prog='generate-notifyrc',
        description='Generate .notifyrc files for the event registration subsystem')
    parser.add_argument('-o', '--output', default=str(NOTIFY_RC_DIR_PATH), help='Specify output directory for files')
    return parser


def load_events():
    for group_dir in filter(lambda d: d.is_dir(), ModAstraEventsLoader.default_settings_dir.iterdir()):
        try:
            group_settings = load_json(group_dir / group_dir.name).get('group-params')

            if group_dir.name in special_groups:
                group = special_groups.get(group_dir.name)
                if not group:
                    print(f"Skipping group {group_dir.name}: no group settings found.")
                    continue
            else:
                group_name_ru = group_settings.get('name_ru')
                group_name_en = group_settings.get('name_en')
                if not all([group_name_ru, group_name_en]):
                    raise Exception(f"Group {group_dir.name} is missing required name parameters (name_ru or name_en).")
                group = AstraEventGroup(group_dir.name, group_name_ru, group_name_en)

            if group_dir.name in missing_events_by_group:
                group.events.extend(missing_events_by_group[group_dir.name])

            for event_settings_file in filter(lambda f: f.is_file() and f.name != group_dir.name, group_dir.iterdir()):
                try:
                    event_settings = load_json(event_settings_file)
                    message_params = event_settings.get('message-params')
                    message_id = message_params.get('message_id')
                    event_name_ru = message_params.get('name_ru')
                    event_name_en = message_params.get('name_en')
                    if not all([message_id, event_name_ru, event_name_en]):
                        raise Exception(f"{event_settings_file.name} event config is missing required parameters.")

                    event = AstraEvent(message_id, event_name_ru, event_name_en)
                    group.events.append(event)
                except Exception as e:
                    print(f"Error processing event file {event_settings_file.name}: {e}")

            astra_events.append(group)
        except Exception as e:
            print(f"Error processing group {group_dir.name}: {e}")

def configure_notify_rc(output_dir: Path):
    def to_camel_case(string: str) -> str:
        parts = string.split('_')
        return parts[0] + ''.join(word.capitalize() for word in parts[1:])

    for group in astra_events:
        config = configparser.ConfigParser()
        config.optionxform = str

        config['Global'] = {
            'IconName': 'preferences-system-events',
            'Name': 'Event registration: ' + group.name_en,
            'Name[ru]': 'Регистрация событий: ' + group.name_ru,
            'Comment': 'Event registration: ' + group.name_en,
            'Comment[ru]': 'Регистрация событий: ' + group.name_ru,
        }

        for event in group.events:
            config[f'Event/{to_camel_case(event.id)}'] = {
                'Name': event.name_en,
                'Name[ru]': event.name_ru,
                'Action': 'Popup',
            }

        with Path(output_dir / f'astra-event-watcher_{group.id}.notifyrc').open('w') as file:
            config.write(file, False)


if __name__ == '__main__':
    args = create_argument_parser().parse_args()
    output_dir_path = Path(args.output)
    if not output_dir_path.exists():
        print(f'Output directory {output_dir_path} does not exist. Cannot generate .notifyrc files')
        exit(0)

    load_events()
    configure_notify_rc(output_dir_path)
