#! /usr/bin/python3

"""
Rotate backups with appropriate rsnapshot level(s).
{% if 'timing_plan' in item.value %}
{% set timing_plan = item.value.timing_plan %}
{% else %}
{% set timing_plan = 'normal' %}
{% endif %}
{% if timing_plan in rsnapshot_push_defaults.timing_plans %}
{% set plan = rsnapshot_push_defaults.timing_plans[timing_plan] %}
{% endif %}
{% if 'timing_plans' in rsnapshot_push and timing_plan in rsnapshot_push.timing_plans %}
{% set plan = rsnapshot_push.timing_plans[timing_plan] %}
{% endif %}
"""

import json
import time
import subprocess

DB = "{{ '/'.join([rsnapshot_push.backup_dir, item.key, 'rsnapshot_push.db']) }}"
CONFIG = "{{ '/'.join([rsnapshot_push.backup_dir, item.key, 'rsnapshot.conf']) }}"
LEVELS = {
{% for name, spec in plan.items() %}
    '{{ name }}': {{ spec[0] }},
{% endfor %}
}


def _get_db():
    try:
        with open(DB, 'r') as fdb:
            db_dict = json.loads(fdb.read())
    except FileNotFoundError:
        db_dict = {}
    # initiate the levels which are not yet in DB
    now = time.time()
    force_reset = False
    for key in LEVELS:
        if key not in db_dict or force_reset:
            db_dict[key] = now
            force_reset = True
    return db_dict


def rotate(database):
    """ rotate backups as needed, per last runs stored in database """
    now = time.time()
    for level, delay in sorted(LEVELS.items(), key=lambda x: x[1]):
        cmd = ['/bin/rsnapshot', '-c', CONFIG, level]
        last_run = database[level]
        if (now - last_run) > delay:
            print("running " + ' '.join(cmd))
            subprocess.check_call(cmd)
            database[level] = now
        else:
            print("skipping " + level)


def _main():
    database = _get_db()
    try:
        rotate(database)
    finally:
        with open(DB, 'w') as fdb:
            fdb.write(json.dumps(database))


if __name__ == "__main__":
    _main()
