from datetime import datetime
from os import listdir
from os.path import isfile, join
from subprocess import check_output

zone_path = join(repo.path, 'data', 'powerdns', 'files', 'bind-zones')

ZONE_HEADER = """
;      _    ____ _   _ _____ _   _ _   _  ____
;     / \\  / ___| | | |_   _| | | | \\ | |/ ___|
;    / _ \\| |   | |_| | | | | | | |  \\| | |  _
;   / ___ \\ |___|  _  | | | | |_| | |\\  | |_| |
;  /_/   \\_\\____|_| |_| |_|  \\___/|_| \\_|\\____|
;
; --> Diese Datei wird von BundleWrap verwaltet! <--

$TTL 60
@       IN  SOA ns-1.kunbox.net.    hostmaster.kunbox.net. (
        {serial}
        3600
        600
        86400
        300
    )
"""
for rnode in sorted(repo.nodes_in_group('dns')):
    ZONE_HEADER += '@       IN  NS {}.\n'.format(rnode.metadata.get('powerdns/my_hostname', rnode.metadata.get('hostname')))

directories = {
    '/etc/powerdns/pdns.d': {
        'purge': True,
        'needs': {
            'pkg_apt:pdns-server',
            'pkg_apt:pdns-backend-bind',
            'pkg_apt:pdns-backend-pgsql',
        },
        'triggers': {
            'svc_systemd:pdns:restart',
        },
    },
    '/var/lib/powerdns/zones': {
        'purge': True,
        'needs': {
            'pkg_apt:pdns-backend-bind',
        },
    }
}

files = {
    '/etc/powerdns/pdns.conf': {
        'content_type': 'mako',
        'context': {
            'api_key': node.metadata['powerdns']['api_key'],
            'my_hostname': node.metadata['powerdns'].get('my_hostname', node.metadata.get('hostname')),
            'is_secondary': node.metadata['powerdns'].get('is_secondary', False),
            'my_primary_servers': node.metadata['powerdns'].get('my_primary_servers', set()),
            'my_secondary_servers': node.metadata['powerdns'].get('my_secondary_servers', set()),
        },
        'needs': {
            'pkg_apt:pdns-server',
        },
        'triggers': {
            'svc_systemd:pdns:restart',
        },
    },
}

svc_systemd = {
    'pdns': {
        'needs': {
            'pkg_apt:pdns-server',
            'pkg_apt:pdns-backend-bind',
            'pkg_apt:pdns-backend-pgsql',
        },
    },
}

actions = {
    'powerdns_reload_zones': {
        'triggered': True,
        'command': 'pdns_control rediscover; pdns_control reload',
        'needs': {
            'svc_systemd:pdns',
        },
    },
}

if node.metadata.get('powerdns/features/bind', False):
    primary_zones = set()
    for zone in listdir(zone_path):
        if not isfile(join(zone_path, zone)) or zone.startswith(".") or zone.startswith("_"):
            continue

        try:
            output = check_output(['git', 'log', '-1', '--pretty=%ci', join(zone_path, zone)]).decode('utf-8').strip()
            serial = datetime.strptime(output, '%Y-%m-%d %H:%M:%S %z').strftime('%y%m%d%H%M')
        except:
            serial = datetime.now().strftime('%y%m%d0000')

        primary_zones.add(zone)

        files[f'/var/lib/powerdns/zones/{zone}'] = {
            'content_type': 'mako',
            'context': {
                'header': ZONE_HEADER.format(serial=serial),
                'metadata_records': node.metadata.get(f'powerdns/bind-zones/{zone}/records', []),
            },
            'source': f'bind-zones/{zone}',
            # TODO enable this once bundlewrap has test_with
            # was introduced in https://github.com/bundlewrap/bundlewrap/commit/cb7e9c161719acd70d132a7b24f0d231a8cb3fa3
            #'test_with': f'named-checkzone {zone} {{}}',
            'triggers': {
                'action:powerdns_reload_zones',
            },
            'needed_by': {
                'svc_systemd:pdns',
            },
        }

    files['/etc/powerdns/pdns.d/bind.conf'] = {
        'needs': {
            'pkg_apt:pdns-backend-bind',
        },
        'needed_by': {
            'svc_systemd:pdns',
        },
        'triggers': {
            'action:powerdns_reload_zones',
        },
    }

    files['/etc/powerdns/named.conf'] = {
        'content_type': 'mako',
        'context': {
            'zones': primary_zones,
        },
        'needs': {
            'pkg_apt:pdns-backend-bind',
        },
        'needed_by': {
            'svc_systemd:pdns',
        },
        'triggers': {
            'action:powerdns_reload_zones',
        },
    }

if node.metadata.get('powerdns/features/pgsql', False):
    files['/etc/powerdns/pdns.d/pgsql.conf'] = {
        'content_type': 'mako',
        'context': {
            'password': node.metadata['postgresql']['roles']['powerdns']['password'],
        },
        'needs': {
            'pkg_apt:pdns-backend-pgsql',
        },
        'needed_by': {
            'svc_systemd:pdns',
        },
        'triggers': {
            'action:powerdns_reload_zones',
        },
    }

    files['/etc/powerdns/schema.pgsql.sql'] = {}

    actions['powerdns_load_pgsql_schema'] = {
        'command': node.metadata['postgresql']['roles']['powerdns']['password'].format_into('PGPASSWORD={} psql -h 127.0.0.1 -d powerdns -U powerdns -w < /etc/powerdns/schema.pgsql.sql'),
        'unless': 'sudo -u postgres psql -d powerdns -c "\dt" | grep domains 2>&1 >/dev/null',
        'needs': {
            'bundle:postgresql',
            'file:/etc/powerdns/schema.pgsql.sql',
        },
        'needed_by': {
            'svc_systemd:pdns',
        },
    }