import shutil
import csv
import os
import os.path
import datetime as dt

from django.core.management.base import BaseCommand, CommandError
import django.contrib.auth.models as auth_models
from django.db import transaction
from django.conf import settings

from ... import models
from ... import timestamp
from ....log import models as log_models

class Command(BaseCommand):
    args = '<directory>'
    help = 'Save logs, and user list'

    def dict_to_utf8(self, d):
        for key in d:
            d[key] = d[key].encode('utf8')

    def save_users(self, path):
        with open(os.path.join(path, 'users.csv'), 'w') as f:
            headers = ['username', 
                       'prenom', 
                       'nom', 
                       'email', 
                       'profil', 
                       'groupe']
            csv_handle = csv.DictWriter(f, headers)
            users = auth_models.User.objects.filter(is_superuser=False)
            csv_handle.writerow(dict(zip(csv_handle.fieldnames, csv_handle.fieldnames)))
            if not users.count():
                raise CommandError('No users, nothing to archive !! Already archived maybe...')
            for user in users:
                d = {
                    'username': user.username,
                    'prenom': user.first_name,
                    'nom': user.last_name,
                    'email': user.email,
                    'profil': ','.join([ml.name for ml in user.mailing_lists.all()]),
                    'groupe': ','.join([group.name for group in user.groups.all()])}
                self.dict_to_utf8(d)
                csv_handle.writerow(d)
            users.delete()

    def save_logs(self, path):
        with open(os.path.join(path, 'log.csv'), 'w') as f:
            headers = ['timestamp', 
                       'name', 
                       'levelname', 
                       'ip', 
                       'user', 
                       'message']
            csv_handle = csv.DictWriter(f, headers)
            csv_handle.writerow(dict(zip(csv_handle.fieldnames, csv_handle.fieldnames)))
            logs = log_models.LogLine.objects.all()
            for log in logs:
                d = dict([(header, getattr(log, header)) for header in headers])
                d['timestamp'] = d['timestamp'].isoformat()
                self.dict_to_utf8(d)
                csv_handle.writerow(d)
            logs.delete()

    def timestamp_logs(self, path):
        with open(os.path.join(path, 'log-timestamp.der'), 'w') as f:
            with open(os.path.join(path, 'log.csv')) as log_handle:
                tst, message = timestamp.timestamp(log_handle.read())
                if not tst:
                    raise CommandError('Failure to compute the timestamp: %s' % message)
            f.write(tst)

    def remove_profiles(self):
        models.MailingList.objects.all().delete()

    def removal_error(self, function, path, excinfo):
        print 'unable to delete %s: %s' % (path, excinfo[1])

    @transaction.commit_on_success
    def handle(self, *args, **options):
        directory = args[0]
        path = os.path.join(directory, dt.datetime.now().isoformat())
        os.mkdir(path)
        try:
            self.save_users(path)
            self.remove_profiles()
            self.save_logs(path)
            self.timestamp_logs(path)
            file_dir = os.path.join(settings.MEDIA_ROOT, 'files/')
            print 'Removing %s...' % file_dir
            shutil.rmtree(file_dir, onerror=self.removal_error)
            upload_dir = os.path.join(settings.MEDIA_ROOT, 'upload/')
            print 'Removing %s...' % upload_dir
            shutil.rmtree(upload_dir, onerror=self.removal_error)
            print 'Creating %s...' % file_dir
            os.mkdir(file_dir)
            print 'Creating %s...' % upload_dir
            os.mkdir(upload_dir)
        except:
            shutil.rmtree(path)
            raise
