import logging
import os
import plistlib

import click
import coloredlogs

NOTIFICATIONS_FILENAME = os.path.join(os.path.dirname(__file__), 'notifications.txt')

coloredlogs.install(level=logging.DEBUG)


def get_notifications():
    with open(NOTIFICATIONS_FILENAME, 'rb') as f:
        return f.read().decode().split('\n')


def save_notifications(notifications):
    with open(NOTIFICATIONS_FILENAME, 'wb') as f:
        f.write('\n'.join(notifications).encode())


@click.command()
@click.argument('root_fs', type=click.Path(dir_okay=True, file_okay=False, exists=True))
def main(root_fs):
    """
    Add notifications registered to `com.apple.notifyd.matching` from a given IPSW `root_fs` (extracted filesystem)
    into `notifications.txt`
    """
    launch_daemons = os.path.join(root_fs, 'System', 'Library', 'LaunchDaemons')

    notifications = set(get_notifications())

    for filename in os.listdir(launch_daemons):
        if not filename.endswith('.plist'):
            continue

        filename = os.path.join(launch_daemons, filename)
        with open(filename, 'rb') as f:
            plist = plistlib.load(f)

        launch_events = plist.get('LaunchEvents', {})
        notifyd_matching = launch_events.get('com.apple.notifyd.matching', {})

        for v in notifyd_matching.values():
            if not isinstance(v, dict):
                logging.error(f'error parsing: {filename}')
                continue
            notification = v.get('Notification')
            if notification is None:
                continue

            if notification not in notifications:
                logging.info(f'adding notification: {notification}')
                notifications.add(notification)

    save_notifications(notifications)


if __name__ == '__main__':
    main()
