from itertools import count
from os import listdir
from os.path import isdir, isfile, join
from pathlib import Path
from uuid import UUID

from bundlewrap.metadata import metadata_to_json

for row in Path(join(repo.path, 'bundles', 'grafana', 'dashboard-rows')).rglob("*.py"):
    with open(row, 'r') as f:
        exec(f.read())

directories = {
    # Don't ask me why these permissions are that weird. It's what the
    # debian package sets them to after upgrades.
    '/etc/grafana/provisioning/dashboards': {
        'group': 'grafana',
        'purge': True,
    },
    '/etc/grafana/provisioning/datasources': {
        'group': 'grafana',
        'purge': True,
    },
    '/etc/grafana/provisioning/notifiers': {
        'group': 'grafana',
        'purge': True,
    },
    '/etc/grafana/provisioning/plugins': {
        'group': 'grafana',
        'purge': True,
    },
    '/var/lib/grafana/dashboards': {
        'owner': 'grafana',
        'group': 'grafana',
        'purge': True,
        'triggers': {
            'svc_systemd:grafana-server:restart',
        },
    },
}

files = {
    '/etc/grafana/grafana.ini': {
        'content_type': 'mako',
        'context': node.metadata['grafana'],
        'group': 'grafana',
        'mode': '0640',
        'triggers': {
            'svc_systemd:grafana-server:restart',
        },
    },
    '/etc/grafana/provisioning/dashboards/bundlewrap.yaml': {
        'source': 'dashboards.yaml',
        'group': 'grafana',
        'mode': '0640',
        'triggers': {
            'svc_systemd:grafana-server:restart',
        },
    },
}

svc_systemd = {
    'grafana-server': {
        'needs': {
            'file:/etc/grafana/grafana.ini',
            'pkg_apt:grafana',
        },
    },
}

### dashboard management starts here
for rnode in repo.nodes:
    if not rnode.has_bundle('telegraf'):
        continue

    panel_id = count(start=1)
    dashboard = {
        'title': rnode.name,
        'uid': UUID(int=rnode.magic_number).hex[:10],

        'editable': False,
        'graphTooltip': 1,
        'schemaVersion': 12,
        'style': 'dark',
        'tags': {'bw'},
        'time': {
            'from': 'now-1d',
            'to': 'now'
        },
        'version': 1,

        'rows': [
            dashboard_row_cpu(panel_id, rnode),
            dashboard_row_ip_traffic(panel_id, rnode),
            dashboard_row_memory(panel_id, rnode),
        ],
    }

    if rnode.has_bundle('ipmitool'):
        dashboard['rows'].append(dashboard_row_ipmitool(panel_id, rnode))
        dashboard['tags'].add('ipmitool')
    elif rnode.has_bundle('lm-sensors'):
        dashboard['rows'].append(dashboard_row_sensors(panel_id, rnode))
        dashboard['tags'].add('lm-sensors')

    if rnode.has_bundle('smartd'):
        dashboard['rows'].append(dashboard_row_smartd(panel_id, rnode))
        dashboard['tags'].add('smartd')

    if rnode.has_bundle('telegraf-battery-usage'):
        dashboard['rows'].append(dashboard_row_battery(panel_id, rnode))

    dashboard['rows'].append(dashboard_row_disk_space(panel_id, rnode))
    dashboard['rows'].append(dashboard_row_disk_iops(panel_id, rnode))

    if rnode.has_bundle('nginx'):
        dashboard['rows'].append(dashboard_row_nginx(panel_id, rnode))
        dashboard['tags'].add('nginx')

    if rnode.has_bundle('postfix'):
        dashboard['rows'].append(dashboard_row_postfix(panel_id, rnode))
        dashboard['tags'].add('postfix')

    if rnode.has_bundle('dovecot'):
        dashboard['rows'].append(dashboard_row_dovecot(panel_id, rnode))
        dashboard['tags'].add('dovecot')

    if rnode.has_bundle('rspamd'):
        dashboard['rows'].append(dashboard_row_rspamd(panel_id, rnode))
        dashboard['tags'].add('rspamd')

    if rnode.has_bundle('postgresql'):
        dashboard['rows'].append(dashboard_row_postgresql(panel_id, rnode))
        dashboard['tags'].add('postgresql')

    if rnode.has_bundle('wireguard'):
        dashboard['rows'].append(dashboard_row_wireguard(panel_id, rnode))
        dashboard['tags'].add('wireguard')

    if rnode.has_bundle('zfs'):
        dashboard['rows'].append(dashboard_row_zfs(panel_id, rnode))
        dashboard['tags'].add('zfs')

    if rnode.has_bundle('unbound'):
        dashboard['rows'].append(dashboard_row_unbound(panel_id, rnode))
        dashboard['tags'].add('unbound')

    files[f'/var/lib/grafana/dashboards/{rnode.name}.json'] = {
        'owner': 'grafana',
        'group': 'grafana',
        # use metadata_to_json, because this supports sets
        'content': metadata_to_json(dashboard),
        'triggers': {
            'svc_systemd:grafana-server:restart',
        },
    }


additional_path = join(repo.path, 'data', 'grafana', 'files', node.name, 'dashboards')
if isdir(additional_path):
    for file in listdir(additional_path):
        if not isfile(join(additional_path, file)) or file.startswith('.') or file.startswith('_'):
            continue

        files[f'/var/lib/grafana/dashboards/{file}'] = {
            'owner': 'grafana',
            'group': 'grafana',
            'source': join(node.name, 'dashboards', file),
            'triggers': {
                'svc_systemd:grafana-server:restart',
            },
        }
