#import re

defaults = {
    'apt': {
        'packages': {
            'zfs-dkms': {
                'needed_by': {
                    'pkg_apt:zfs-zed',
                    'pkg_apt:zfsutils-linux',
                },
            },
            'zfs-zed': {
                'needed_by': {
                    'svc_systemd:zfs-zed',
                    'zfs_dataset:',
                    'zfs_pool:',
                },
            },
            'zfsutils-linux': {
                'needed_by': {
                    'pkg_apt:zfs-zed',
                    'zfs_dataset:',
                    'zfs_pool:',
                },
            },
            'parted': {
                'needed_by': {
                    'zfs_pool:',
                },
            },
        },
    },
    'icinga2_api': {
        'zfs': {
            'services': {
                'ZFS AUTO SNAPSHOT': {
                    'command_on_monitored_host': 'sudo /usr/local/share/icinga/plugins/check_zfs_auto_snapshot',
                },
                'ZFS MOUNTED VOLUMES': {
                    'command_on_monitored_host': 'sudo /usr/local/share/icinga/plugins/check_zfs_volumes',
                    'vars.notification.mail': True,
                },
            },
        },
    },
    'pacman': {
        'no_extract': {
            'etc/sudoers.d/zfs',
        },
        'packages': {
            'zfs-utils': {
                'needed_by': {
                    'svc_systemd:zfs-zed',
                },
            },
        },
    },
    'systemd-timers': {
        'timers': {
            'zfs-auto-snapshot-daily': {
                'when': 'daily',
                'command': '/usr/local/sbin/zfs-auto-snapshot daily',
            },
            'zfs-auto-snapshot-hourly': {
                'when': 'hourly',
                'command': '/usr/local/sbin/zfs-auto-snapshot hourly',
            },
            'zfs-auto-snapshot-monthly': {
                'when': 'monthly',
                'command': '/usr/local/sbin/zfs-auto-snapshot monthly',
            },
            'zfs-auto-snapshot-weekly': {
                'when': 'weekly',
                'command': '/usr/local/sbin/zfs-auto-snapshot weekly',
            },
        },
    },
    'zfs': {
        'datasets': {},
        'pools': {},
        'snapshots': {
            'retain_defaults': {
                'hourly': 24,
                'daily': 7,
                'weekly': 2,
                'monthly': 1,
            },
        },
    },
}

if node.os == 'debian' and node.os_version[0] <= 10:
    defaults['apt']['repos'] = {
        'backports': {
            'install_gpg_key': False, # default debian signing key
            'items': {
                'deb http://deb.debian.org/debian {os_release}-backports main',
            },
        },
    }

if node.has_bundle('telegraf'):
    defaults['telegraf'] = {
        'input_plugins': {
            'builtin': {
                'zfs': [{
                    'poolMetrics': True,
                }],
            },
            'exec': {
                'zfs-dataset': {
                    'commands': ['sudo /usr/local/sbin/telegraf-per-dataset'],
                    'data_format': 'influx',
                    'timeout': '5s',
                },
            },
        },
        'sudo_commands': {
            '/usr/local/sbin/telegraf-per-dataset',
        },
    }


@metadata_reactor.provides(
    'pacman/packages',
)
def packages(metadata):
    if node.metadata.get('pacman/linux-lts', False):
        pkgname = 'zfs-linux-lts'
    else:
        pkgname = 'zfs-linux'
    return {
        'pacman': {
            'packages': {
                pkgname: {
                    'needed_by': {
                        'zfs_dataset:',
                        'zfs_pool:',
                    },
                },
            },
        },
    }

@metadata_reactor.provides(
    'apt/packages',
)
def linux_headers(metadata):
    cpu_arch = metadata.get('cpu_arch', 'amd64')

    return {
        'apt': {
            'packages': {
                f'linux-headers-{cpu_arch}': {
                    'needed_by': {
                        'pkg_apt:zfs-dkms',
                    },
                },
            },
        },
    }


@metadata_reactor.provides(
    'systemd-timers/timers/zfs-scrub',
)
def scrub_timer(metadata):
    scrubs = [f'zpool scrub {pool}' for pool in sorted(metadata.get('zfs/pools', {}))]
    return {
        'systemd-timers': {
            'timers': {
                'zfs-scrub': {
                    'when': 'Sun 02:00:00 UTC',
                    'command': scrubs,
                },
            },
        },
    }


@metadata_reactor.provides(
    'icinga2_api/zfs/services',
)
def monitoring(metadata):
    if not node.has_bundle('sshmon'):
        raise DoNotRunAgain

    services = {}

    if metadata.get('zfs/enable_old_snapshots_check', True):
        services['ZFS OLD SNAPSHOTS'] = {
            'command_on_monitored_host': 'sudo /usr/local/share/icinga/plugins/check_zfs_old_snapshots',
            'vars.sshmon_timeout': 30,
        }

    for poolname, _ in metadata.get('zfs/pools').items():
        services['ZFS ZPOOL ONLINE {}'.format(poolname)] = {
            'command_on_monitored_host': 'sudo /usr/local/share/icinga/plugins/check_zpool_online {}'.format(poolname),
            'vars.notification.mail': True,
        }

        services['ZFS ZPOOL SPACE ' + poolname] = {
            'command_on_monitored_host': 'sudo /usr/local/share/icinga/plugins/check_zpool_space {} 90'.format(poolname),
            'vars.notification.mail': True,
        }

    return {
        'icinga2_api': {
            'zfs': {
                'services': services,
            },
        },
    }


@metadata_reactor.provides(
    'zfs/filesystems_with_backup_snapshots',
)
def backups_with_snapshot(metadata):
    backups = metadata.get('backups/paths', set())
    datasets = metadata.get('zfs/datasets', {})

    backups_in_zfs_datasets = {}

    for path in backups:
        for dname, dconfig in datasets.items():
            if 'mountpoint' in dconfig:
                if path[:len(dconfig['mountpoint'])] == dconfig['mountpoint']:
                    backups_in_zfs_datasets.setdefault(dname, set()).add(path)

    return {
        'zfs': {
            'filesystems_with_backup_snapshots': backups_in_zfs_datasets,
        },
    }