#!/usr/bin/python3
import os
import socket
import time
from pychromecast import discovery, _get_chromecast_from_host

CC_NAMES = ["Mei", "Madeline"]

device = None

# Callback for start_discovery.
# Has to do quite some stuff manually because of bugs in the library.
def cc_callback(hostname):
    global device
    cc_tmp = _get_chromecast_from_host(
            cast_listener.services[hostname],
            tries=None, retry_wait=None,
            timeout=None,
            blocking=True  # Important, library async is broken here
    )

    try:
        pos = CC_NAMES.index(cc_tmp.device.friendly_name)
    except ValueError:
        return

    if device is not None and pos > CC_NAMES.index(device.device.friendly_name):
        return

    device = cc_tmp
    print(cc_tmp.device.friendly_name, "connected.")


# Start discovery for Chromecast
cast_listener, browser = discovery.start_discovery(cc_callback)

# Setup UNIX socket
socket_path = "/var/run/chromecastd/daemon.sock"

def cleanup_socket():
    try:
        os.unlink(socket_path)
    except FileNotFoundError:
        pass

cleanup_socket()
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind(socket_path)
server.listen(1)

# Main loop
client = None
while True:
    try:
        # Accept new connections from socket
        (client, address) = server.accept()
        received = client.recv(16).decode()
        if device is None:  # Device isn't available in network
            client.send(b"idle")
            client.close()
            client = None
            continue

        device.wait()  # Make sure we have up-to-date information
        media_ctl = device.media_controller
        if device.socket_client.is_connected and media_ctl.is_active:
            if received == "state":
                pass
            elif received == "toggle":
                if media_ctl.is_playing:
                    media_ctl.pause()
                else:
                    media_ctl.play()
            elif received == "play":
                media_ctl.play()
            elif received == "pause":
                media_ctl.pause()
            elif received == "volup":
                device.volume_up()
            elif received == "voldown":
                device.volume_down()
            else:
                print("Invalid argument")

            device.wait()
            time.sleep(0.05)  # 50 ms
            if media_ctl.is_playing:
                client.send(b"playing")
            else:
                client.send(b"paused")
        else:
            client.send(b"idle")
        client.close()
        client = None
    except Exception as e:
        print("Error:", e)
        break

# Clean-up
print("Cleaning up…")
discovery.stop_discovery(browser)  # Stop Chromecast discovery
if client is not None:
    client.close()
cleanup_socket()
