#!/usr/bin/env python3


import re

from datetime import datetime
from json import loads
from subprocess import check_call, check_output
from sys import argv


def create_snap_and_rotate(ds, label, retain, now, all_snapshots):
    new_snap = '{}@zfs-auto-snap_{}-{}'.format(ds, label, now)
    check_call(['zfs', 'snapshot', new_snap])

    prefix = '{}@zfs-auto-snap_{}-'.format(ds, label)
    my_candidates = []
    for i in sorted(all_snapshots):
        if i.startswith(prefix):
            my_candidates.append(i)

    my_candidates.append(new_snap)

    for i in my_candidates[:-retain]:
        assert '@' in i, 'BUG! Dataset "{}" has no @!'.format(i)
        check_call(['zfs', 'destroy', i])


label = argv[1]

with open('/etc/zfs-snapshot-config.json', 'r') as fp:
    metadata = loads(fp.read())

datasets = set()
for line in check_output(['zfs', 'list', '-H', '-o', 'name']).splitlines():
    line = line.decode('UTF-8')

    for prefix in metadata.get('snapshot_never', set()):
        if line.startswith(prefix):
            break
    else:
        datasets.add(line)

default_retain = metadata['retain_defaults'][label]
now = datetime.now().strftime('%F-%H%M')
snapshots_created = False

if datasets:
    all_snapshots = check_output(['zfs', 'list', '-H', '-o', 'name', '-t', 'snap']).decode('UTF-8').splitlines()

    for ds in datasets:
        retain = int(metadata.get('retain_per_dataset', {}).get(ds, {}).get(label, default_retain))
        if retain > 0:
            create_snap_and_rotate(ds, label, retain, now, all_snapshots)
            snapshots_created = True

with open('/var/tmp/zfs-auto-snapshot.status', 'w') as fp:
    fp.write('{}\n'.format(datetime.now().strftime('%s') if snapshots_created else 0))