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

import os
import requests
from uuid import getnode as get_mac

from django.conf import settings
from django.core import serializers
from django.core.management.base import BaseCommand
from django.core.urlresolvers import reverse

from colorama import Fore
from tendo import singleton

from mtp.apps.common.utils import bypass_orderable
from mtp.apps.sync.hooks import run_pre_sync_hooks, run_post_sync_hooks
from mtp.apps.sync.models import Syncable, Task, Update


class Command(BaseCommand):
    args = ''
    help = 'Update server up. Not launch on global server, only on local.'

    def handle(self, *args, **options):
        me = singleton.SingleInstance()

        if settings.INSTANCE_IS_MASTER:
            print("Not local")
            return

        print(Fore.GREEN + 'Run pre-sync hooks' + Fore.RESET)
        run_pre_sync_hooks()
        print(Fore.GREEN + '=> DONE!' + Fore.RESET)

        datas_to_sync = []
        files_to_sync = []
        objs_list = []
        for syncable_model in Syncable.get_syncable_models():
            objs = syncable_model.objects.filter(update_locally=True)
            if hasattr(syncable_model, "original"):
                objs = objs.order_by("-original")
            objs_list.append(objs)
            for obj in objs:
                datas_to_sync = datas_to_sync + obj.get_sync_objects()
                files_to_sync = files_to_sync + obj.get_sync_files()

        if len(datas_to_sync) == 0:
            return

        print((Fore.GREEN + "Data uploaded:" + Fore.RESET))
        for d in datas_to_sync:
            print(d.__class__.__name__ + ": " + str(d))
        print((Fore.GREEN + "Files to upload:" + Fore.RESET))
        for f in files_to_sync:
            print(f)

        json = serializers.serialize('json', datas_to_sync)
        mac = get_mac()
        params = {
            'json_stream': json,
            'mac': "%d" % mac
        }
        update_up_url = settings.MASTER_INSTANCE_URL + reverse('sync:upload')
        
        response = requests.post(update_up_url, params)

        with bypass_orderable():  # Keep order from objects in the response

            for deserialized_object in serializers.deserialize("json", response.text):
                deserialized_object.save()

        last_update = Update.objects.all()[0]
        for objs in objs_list:
            objs.update(last_update=last_update, update_locally=False)

        # FIXME: need to set last update to healthy <-- MR: Isn't it done just below?
        last_update.healthy = True
        last_update.save()

        print("DB synchronized")

        upload_url = settings.MASTER_INSTANCE_URL + \
            settings.UPLOAD_SYNC_URL + '?' + '%d' % (get_mac())
        for f in files_to_sync:
            if f['name'] == '':
                continue

            file_name = os.path.join(settings.MEDIA_ROOT, f['name'])
            t = Task(path='curl -F "file=@%s" -F "filename=%s" -F "folder=%s" %s' % (file_name, os.path.basename(f['name']), os.path.dirname(f['name']), upload_url),
                     finish_path='echo "Finish"')
            t.save()

        print(Fore.GREEN + 'Run post-sync hooks' + Fore.RESET)
        run_post_sync_hooks()
        print(Fore.GREEN + '=> DONE!' + Fore.RESET)
