#!/usr/bin/env python3

import subprocess, sys
import math, time, datetime

if len(sys.argv)!=4:
    print ("Usage: dry_run host dataset")
    print ("dry_run: 0 or 1. 1 is for dry run. 0 - commit changes.")
    print ("host: for example: user@host")
    print ("dataset: for example: tank/dropbox")
    exit(1)

dry_run=int(sys.argv[1])
if dry_run not in [0,1]:
    print ("dry_run option must be 0 or 1")
    exit(0)

host=sys.argv[2]
dataset=sys.argv[3]

def get_snapshots_list():
    rt={}
    with subprocess.Popen(["ssh", host, "zfs list -t snapshot "+dataset],stdout=subprocess.PIPE, bufsize=1,universal_newlines=True) as process:
        for line in process.stdout:
            if "NAME" in line:
                continue
            line=line.rstrip().split(' ')[0]
            line2=line.split('_')[0].split('@')[1]
            rt[int(line2)]=line
    return rt

snapshots=get_snapshots_list()

# These parameters are to be tuned if you want different logarithmic 'curve'...
points=sorted(list(set([math.floor(1.09**x) for x in range(1,120+1)])))

# points in hours
#print (points)

now=math.floor(time.time())

# points in UNIX timestamps
SECONDS_IN_HOUR=60*60
points_TS=sorted(list(map(lambda x: now-x*SECONDS_IN_HOUR, points)), reverse=True)
points_TS.append(0) # remove the oldest snapshot, if it's not in range

prev=now

# we are going to keep only one snapshots between each range
# a snapshot to be picked randomly, or just the first/last
# if there is only one snapshot in the range, leave it
for p in points_TS:
    print ("range", prev, p, datetime.datetime.fromtimestamp(prev), datetime.datetime.fromtimestamp(p))
    range_hi=prev
    range_lo=p
    print ("snapshots between:")
    snapshots_between={}
    for s in snapshots:
        # half-closed interval:
        if s>range_lo and s<=range_hi:
            print (s, snapshots[s])
            snapshots_between[s]=snapshots[s]
    print ("snapshots_between total:", len(snapshots_between))
    if len(snapshots_between)>1:
        snapshots_between_vals=list(snapshots_between.values())
        # going to kill all snapshots except the first
        print ("keeping this snapshot:", snapshots_between_vals[0])
        for to_kill in snapshots_between_vals[1:]:
            print ("removing this snapshot:", to_kill)
            if dry_run==0:
                process=subprocess.Popen(["ssh", host, "zfs destroy "+to_kill])
                process.wait()
    prev=p
