# -*- coding: utf-8 -*-

from zipfile import ZipFile, ZIP_DEFLATED
from datetime import datetime
from os import walk, unlink, environ
from os.path import join as osjoin
from os.path import isfile
from glob import glob
from remote import sync

# Backup plan for Docker volumes
# ::::::::::::::::::::::::::::::
#
# Keep :
#
# - all saves the last week
# - one save per week the last month
# - one save per month during 6 months

# Volumes Backup
# ==============

DEST = environ.get('DEST')
dt = datetime.now()
zipname = '{0}.zip'.format(dt.strftime('%Y-%m-%d_%Hh%Mm%Ss'))
zippath = DEST + zipname

# Zip files

EXCLUDE_WORDS = environ.get('EXCLUDE_WORDS', False)
if EXCLUDE_WORDS:
    EXCLUDE_WORDS = EXCLUDE_WORDS.split(',')

def zipdir(path, ziph):
    # ziph is zipfile handle
    for root, dirs, files in walk(path):
        for file in files:
            pfile = osjoin(root, file)
            is_excluded = EXCLUDE_WORDS and any(map(lambda w: w in pfile, EXCLUDE_WORDS))
            if (isfile(pfile) and not is_excluded):
                ziph.write(pfile)

print('Compression started')
f = ZipFile(zippath, 'w', ZIP_DEFLATED, allowZip64=True)
zipdir('%s/volumes' % DEST, f)
f.close()
print('Compression ended')

# Filter all obsolete save files
# ==============================

PLAN = environ.get('PLAN', u'180,15,2')
PLAN = map(int, PLAN.split(u','))

def notkeep(fname):
    fname = fname.split('/')[-1]
    ds = fname.split('_')
    if len(ds) <= 1:
        return False
    ds = ds[0]
    d = datetime.strptime(ds, '%Y-%m-%d')
    delta = dt - d
    if delta.days > PLAN[0]:
        return True
    elif delta.days > PLAN[1]:
        if d.day != 1:
            return True
    elif delta.days > PLAN[2]:
        if (d.weekday() != 0) and (d.day != 1):
            return True
    else:
        return False

# Filters zip files and keeps only legitimate ones
# ================================================

files = glob('%s/*.zip' % DEST)
backups_to_remove = filter(notkeep, files)

if len(backups_to_remove) > 0:
    print('Save files outdated, will be deleted : \n\n* ' +
          '\n* '.join(backups_to_remove))

for b in backups_to_remove:
    unlink(b)

sync()