#!/usr/bin/env python3
import logging
import os
import sys
import threading
from pathlib import Path

from StreamDeck.DeviceManager import DeviceManager

from devdeck.devdeck import DevDeck
from devdeck.settings.devdeck_settings import DevDeckSettings
from devdeck.settings.validation_error import ValidationError

if __name__ == "__main__":
    root = logging.getLogger('devdeck')
    root.setLevel(logging.DEBUG)

    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    root.addHandler(handler)

    streamdecks = DeviceManager().enumerate()

    settings_filename = os.path.join(str(Path.home()), '.devdeck', 'settings.yml')
    if not os.path.exists(settings_filename):
        root.warning("No settings file detected!")

        serial_numbers = []
        for index, deck in enumerate(streamdecks):
            deck.open()
            serial_numbers.append(deck.get_serial_number())
            deck.close()
        if len(serial_numbers) > 0:
            root.info("Generating a setting file as none exist: %s", settings_filename)
            os.makedirs(os.path.join(str(Path.home()), '.devdeck'), exist_ok=True)
            DevDeckSettings.generate_default(settings_filename, serial_numbers)
        else:
            root.info("""No stream deck connected. Please connect a stream deck to generate an initial config file. \n
                         If you are having difficulty detecting your stream deck please follow the installation
                         instructions: https://github.com/jamesridgway/devdeck/wiki/Installation""")
            exit(0)

    try:
        settings = DevDeckSettings.load(settings_filename)
    except ValidationError as validation_error:
        print(validation_error)

    for index, deck in enumerate(streamdecks):
        deck.open()
        root.info('Connecting to deck: %s (S/N: %s)', deck.id(), deck.get_serial_number())

        deck_settings = settings.deck(deck.get_serial_number())
        if deck_settings is None:
            root.info("Skipping deck %s (S/N: %s) - no settings present", deck.id(), deck.get_serial_number())
            deck.close()
            continue

        dev_deck = DevDeck(deck)

        # Instantiate deck
        main_deck = deck_settings.deck_class()(None, **deck_settings.settings())
        dev_deck.set_active_deck(main_deck)

        for t in threading.enumerate():
            if t is threading.currentThread():
                continue

            if t.is_alive():
                try:
                    t.join()
                except KeyboardInterrupt as ex:
                    dev_deck.close()
                    deck.close()
