#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Standard Library
import logging
import threading

from . import utils

try:
    # External Dependencies
    import cec
except ImportError:
    pass

logger = logging.getLogger(__name__)


class CECController(threading.Thread):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.daemon = True
        self.adapter = None
        self.tv = None
        self.mapping = {
            "is_active": self.set_active,
            "is_inactive": self.set_inactive,
            "power_on": self.power_on,
            "power_off": self.power_off,
        }

    def run(self):
        logger.info("HDMI-CEC: Starting up...")
        try:
            cec.init()
            logger.info("HDMI-CEC: Initialized")
        except (Exception, NameError):  # pylint: disable=broad-exception-caught
            logger.info("HDMI-CEC: Failed to initialize")

        try:
            self.adapter = cec.Adapter(name=utils.get_friendly_name(), type=cec.CECDEVICE_PLAYBACKDEVICE1)
        except NameError:
            pass

        self.register_callbacks()

        try:
            self.adapter.list_devices()
            self.tv = cec.Device(self.adapter, cec.CECDEVICE_TV)
        except NameError:
            pass

        while True:
            event, args = utils.ironcast.cec_queue.get(block=True)
            logger.info("HDMI-CEC: [%s] %s", event, repr(args))
            self.mapping[event](*args)

    def set_osd(self, msg):
        try:
            cec.transmit(cec.CECDEVICE_TV, cec.CEC_OPCODE_SET_OSD_NAME, msg.encode("utf-8"))
        except NameError:
            pass

    def register_callbacks(self):
        bitmask = cec.EVENT_KEYPRESS | cec.EVENT_COMMAND | cec.EVENT_ALERT
        bitmask |= cec.EVENT_ACTIVATED | cec.EVENT_MENU_CHANGED
        try:
            self.adapter.add_callback(self.log_callbacks, bitmask)
        except AttributeError:
            pass

    def _log_callbacks(self, *args, **kwargs):
        logger.debug("HDMI: Event: %s %s", repr(args), repr(kwargs))

    def close(self):
        try:
            self.adapter.close()
        except NameError:
            pass

    def set_active(self):
        try:
            cec.set_active_source()
        except NameError:
            pass

    def set_inactive(self):
        pass

    def power_on(self):
        try:
            self.tv.power_on()
        except AttributeError:
            pass

    def power_off(self):
        try:
            self.tv.power_off()
        except AttributeError:
            pass
