from phue import Bridge
import time
import json
import os
import psutil
import atexit
from subprocess import check_output
import datetime

import logging
import logging.handlers
log = logging.getLogger(":")
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
handler = logging.handlers.WatchedFileHandler(
    os.environ.get("LOGFILE", "C:\logs\phue\phue.log"))
formatter = logging.Formatter(logging.BASIC_FORMAT)
handler.setFormatter(formatter)
root = logging.getLogger()
root.addHandler(handler)

def my_log(*argv):
    s = ''
    s += "  " + str(datetime.datetime.now())[0:19] + "  "
    for arg in argv:
        s += str(arg) + " "
    log.info(s)

def on_exit():
    my_log("Setting base settings and exiting!")
    setBrightness(base_brightness)
    setColorTemperature(base_temperature)
    time.sleep(5)

atexit.register(on_exit)

lightsToControl = ['Olli soverom lys', 'stue lys', 'stue lys 2']

b = Bridge("192.168.1.133")
b.connect()
b.get_api()
my_log(json.dumps(b.get_api()['lights'], indent=4, sort_keys=True))

# If color is not same as last set: Save this color as the base color
history_of_set_temperatures = []

from programs import programs

my_log(programs)

current_app = None
running_apps = []


def find_procs_by_name(name):
    "Return a list of processes matching 'name'."
    ls = []
    for p in psutil.process_iter(["name", "exe", "cmdline"]):
        if name == p.info['name'] or \
                p.info['exe'] and os.path.basename(p.info['exe']) == name or \
                p.info['cmdline'] and p.info['cmdline'][0] == name:
            ls.append(p)
    return ls

def flash():
    flash_duration = 0.2
    previous_brightnesses = get_current_brightness()
    setBrightness(254)
    time.sleep(flash_duration)
    setBrightness(0)
    time.sleep(flash_duration)
    setBrightness(previous_brightnesses)

def get_current_temperature():
    return b.get_light(1)['state']['ct']


def get_current_brightness():
    return b.get_light(1)['state']['bri']


def setColorTemperature(ct):
    if ct < 0:
        ct = 0
    my_log("setting color",ct)
    numer_lights = len(b.lights)
    for i in range(1, numer_lights + 1):
        b.set_light(i, 'ct', ct)


def setBrightness(bri):
    my_log("setting brgihtness",bri)
    numer_lights = len(b.lights)
    for i in range(1, numer_lights+1):
        b.set_light(i, 'bri', bri)


base_brightness = get_current_brightness()  # 1 - 254
last_set_brightness = get_current_brightness()
bri_last_iteration = get_current_brightness()

base_temperature = get_current_temperature()  # 155 - 453
last_set_temperature = get_current_temperature()
temp_last_iteration = get_current_temperature()

current_app = "ingen"
while True:
    found_apps = []
    new_apps = []

    for program in programs:
        if find_procs_by_name(program["process_name"]):
            found_apps.append(program)
    found_apps = sorted(found_apps, key=lambda k: k['priority'])

    for running_app in running_apps:
        if running_app not in found_apps:
            my_log("App has closed: ", running_app)

            running_apps.remove(running_app)
            break
    for app in found_apps:
        if app not in running_apps:
            new_apps.append(app)
            running_apps.append(app)
            my_log("new app found: ", app)

    for app in new_apps:
        if app["flash"]:
            flash()
            break
    if len(found_apps) > 0:
        highest_priority_app = found_apps[0]
        if not current_app == highest_priority_app:
            # New highest priority app detected, change lights
            if "color_temperature" in highest_priority_app:
                last_set_temperature = highest_priority_app["color_temperature"]
                setColorTemperature(highest_priority_app["color_temperature"])
            else:
                last_set_temperature = base_temperature
                setColorTemperature(base_temperature)
            if "brightness" in highest_priority_app:
                last_set_brightness = highest_priority_app["brightness"]
                setBrightness(highest_priority_app["brightness"])
            else:
                my_log("setting base brightness",base_brightness)
                last_set_brightness = base_brightness
                setBrightness(base_brightness)

            if "commands" in highest_priority_app:
                for command in highest_priority_app["commands"]:
                    try:
                        my_log("Executing",command,"because of ",highest_priority_app["name"])
                        my_log(check_output(command, shell=True))
                    except:
                        pass


            current_app = highest_priority_app
            my_log("new priority app", highest_priority_app)
        else:
            if current_app == highest_priority_app:
                if "color_temperature" in highest_priority_app and not get_current_temperature() == highest_priority_app["color_temperature"]:
                    time.sleep(5)
                    my_log("external temperature detected, saving new base value",get_current_temperature())
                    base_temperature = get_current_temperature()
                    base_brightness = get_current_brightness()
                if "brightness" in highest_priority_app and not get_current_brightness() == highest_priority_app["brightness"]:
                    time.sleep(5)
                    # Not a new app, but missmatch of brightness
                    my_log("external brightness detected, saving new base value",get_current_brightness())
                    base_brightness = get_current_brightness()
    elif not current_app == "base":
        my_log("setting base")
        last_set_temperature = base_temperature
        setColorTemperature(base_temperature)
        last_set_brightness = base_brightness
        setBrightness(base_brightness)
        current_app = "base"

    if len(found_apps) == 0 and last_set_brightness == base_brightness and not get_current_brightness() == last_set_brightness:
        time.sleep(5)
        my_log("external brightness detected, saving new base value",get_current_brightness())
        base_brightness = get_current_brightness()
    if len(found_apps) == 0 and last_set_temperature == base_temperature and not get_current_temperature() == last_set_temperature:
        time.sleep(5)
        my_log("external temperature detected, saving new base value",get_current_temperature())
        base_temperature = get_current_temperature()

    time.sleep(5)
    bri_last_iteration = get_current_brightness()
    temp_last_iteration = get_current_temperature()
