#!/usr/bin/env python3
import argparse
import os
import re
import glob
import difflib
import datetime


def get_args():
    parser = argparse.ArgumentParser(
        description='backup_diff - show differences')

    parser.add_argument('-H', '--host',
                        required=True,
                        action='store',
                        help='host name, used also as backup filename base ')
    parser.add_argument('-o', '--backupdir',
                        required=True,
                        action='store',
                        help='backup directory')
    parser.add_argument('nums',
                        nargs='*',
                        action='store',
                        type=int,
                        help='create diff between versions')

    args = parser.parse_args()
    return args

def find_backups(backupdir, host):
    basepath = f'{backupdir}/{host}'
    backups = []
    for fn in sorted(glob.glob(f'{basepath}+*/*.lastchange')):
        if m := re.search('\+(\d{4}-\d{2}-\d{2})_(\d\d)(\d\d)(\d\d)', fn):
            moved = f'{m[1]} {m[2]}:{m[3]}:{m[4]}'
        else:
            moved = '(undef)'
        with open(fn, 'r') as f:
            lastchange = f.readlines()[-1].rstrip()
        backups.insert(0, {
            'since': lastchange,
            'until': moved,
            'cfn': re.sub('\.lastchange', '.config', fn)
            })
    try:
        with open(f'{basepath}.lastchange', 'r') as f:
            lastchange = f.readlines()[-1].rstrip()
    except:
        pass
    try:
        info = os.stat(basepath +'.config')
        mtime = datetime.datetime.fromtimestamp(info.st_mtime).strftime('%F %H:%M:%S (latest)')
    except:
        pass
    backups.insert(0, {
            'since': lastchange or '???',
            'until': mtime or '???',
            'cfn': f'{basepath}.config'
            })
    return backups

def diff(backups, host, n1, n2):
    contents = []
    name = []
    for i in (n1, n2):
        if i >= len(backups):
            i = len(backups) - 1
        if i < 0:
            i = 0
        with open(backups[i]['cfn']) as f:
            contents.append(f.readlines())
        name.append(f"[{i:3}] {host} | {backups[i]['since']} - {backups[i]['until']}")
            
    differ = False
    for line in difflib.unified_diff(
            contents[0], contents[1],
            fromfile=name[0], tofile=name[1]
            ):
        print(line.rstrip())
        differ = True
    if not differ:
        print(f'--- {name[0]}')
        print(f'+++ {name[1]}')
        print('no difference')

def main():
    args = get_args()
    backups = find_backups(args.backupdir, args.host)
    if not len(backups):
        print(f'No backups found for host: {args.host}')
        exit(1)

    if len(args.nums) == 1:
        diff(backups, args.host, args.nums[0], 0)
    elif len(args.nums) > 1:
        diff(backups, args.host, args.nums[0], args.nums[1])
    else:
        for i in range(len(backups)-1, -1, -1):
            print(f"{i:3}: {backups[i]['since']} - {backups[i]['until']}")


if __name__ == "__main__":
    main()
# vim: set ft=python tabstop=4 shiftwidth=4 expandtab smarttab:
