import logging
import os
import time
import threading

from dirtrigger import DirTrigger
from migrator import Migrator

class Bunch:
    class TriggeredSource:
        def __init__(self, idx, trigger, migrator, cleanup):
            self.idx = idx
            self.trigger = trigger
            self.migrator = migrator
            self.cleanup = cleanup

    def __init__(self, idx, cache_dir, cfg):
        self._idx = idx
        source_idx = 1
        self._sources = []
        for src_dir_cfg in cfg['src_dirs']:
            reg_db = os.path.join(cache_dir, "reg_%d_%d.db" % (idx, source_idx))
            self._sources.append(
                Bunch.TriggeredSource(
                    source_idx,
                    DirTrigger(src_dir_cfg['path'], src_dir_cfg['cool_time'],
                               src_dir_cfg['max_time']),
                    Migrator(src_dir_cfg['path'], cfg['dst_dir']['path'], reg_db),
                    src_dir_cfg['cleanup']
                )
            )
            source_idx += 1
        logging.info("Created bunch #%d with %d sources.", self._idx, len(self._sources))

    def start(self):
        logging.info("Starting bunch #%d...", self._idx)
        self._stop = False
        self._worker_thread = threading.Thread(target=self._worker)
        self._worker_thread.start()

    def stop(self):
        logging.info("Stopping bunch #%d...", self._idx)
        self._stop = True
        self._worker_thread.join()
        logging.info("Stopped bunch #%d.", self._idx)

    def is_running(self):
        return self._worker_thread.is_alive()

    def _worker(self):
        for src in self._sources:
            src.trigger.start()

        while not self._stop:
            for src in self._sources:
                try:
                    if src.trigger.is_triggering():
                        logging.info("Got trigger for source #%d.%d.", self._idx, src.idx)
                        before = time.time()
                        src.trigger.reset()
                        src.migrator.migrate(src.cleanup)
                        if src.cleanup:
                            src.migrator.cleanup()
                        logging.info("Migration took %.1fs for source #%d.%d.",
                                     time.time() - before, self._idx, src.idx)
                except Exception as e:
                    logging.error("Error migrating source #%d.%d: %s",
                                  self._idx, src.idx, str(e))
            time.sleep(10.0)

        for src in self._sources:
            src.trigger.stop()
