# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4

import os
from threading import Thread
import time

from sqlitedict import SqliteDict

import db
import state
import settings
import update
import utils

import logging
logger = logging.getLogger(__name__)

class Downloads(Thread):

    def __init__(self):
        Thread.__init__(self)
        self.daemon = True
        self.start()
        self._dbpath = os.path.join(settings.data_path, 'transfers.db')
        self.transfers = SqliteDict(self._dbpath, tablename='transfers', autocommit=False)

    def download_updates(self):
        now = int(time.mktime(time.gmtime()))
        if now > settings.server.get('last_update_check', 0) + 24*60*60:
            settings.server['last_update_check'] = now
            update.download()
            state.user().export_library()
            if settings.preferences.get('sendDiagnostics'):
                utils.send_debug()

    def download_next(self):
        import item.models
        self.download_updates()
        downloads = list(self.transfers.items())
        downloads.sort(key=lambda t: t[1].get('added'))
        for itemid, t in downloads:
            if state.shutdown:
                return False
            if itemid not in self.transfers:
                continue
            if t.get('added') and t.get('progress', -1) < 1:
                i = item.models.Item.get(itemid)
                for u in i.users:
                    if state.shutdown:
                        return False
                    if state.nodes.is_online(u.id):
                        logger.debug('DOWNLOAD %s %s', i, u)
                        r = state.nodes.download(u.id, i)
        return False

    def run(self):
        self.wait(10)
        while not state.shutdown:
            self.wait_online()
            with db.session():
                self.download_next()
            self.wait(10)

    def join(self):
        self.transfers.commit()
        self.transfers.close(do_log=False)
        return Thread.join(self)

    def wait_online(self):
        while not state.online:
            self.wait(5)

    def wait(self, timeout):
        step = min(timeout, 1)
        while not state.shutdown and timeout > 0:
            time.sleep(step)
            timeout -= step