import hid
import time
import typing
import struct
from enum import IntEnum

DEFAULT_HID_TIMEOUT = 10
BIGSCREEN_VID = 0x35BD
BEYOND_PID = 0x0101

class Hid_Message(IntEnum):
    RGB_LED = ord('L')
    SUCCESS = ord('$')
    ERROR = ord('E')

def find_beyond_device():
    devices = hid.enumerate()
    beyond_devices = [d for d in devices if d['vendor_id'] == BIGSCREEN_VID and d['product_id'] == BEYOND_PID]
    if beyond_devices:
        return beyond_devices[0]['path']
    return None

def set_rgb_led(red: int, green: int, blue: int) -> bool:
    if(red > 255):
        red = 255
    if(red < 0):
        red = 0
    if(green > 255):
        green = 255
    if(green < 0):
        green = 0
    if(blue > 255):
        blue = 255
    if(blue < 0):
        blue = 0

    device_path = find_beyond_device()
    if not device_path:
        return False
    beyond = hid.device()
    beyond.open_path(device_path)
    beyond.send_feature_report(bytes([0, Hid_Message.RGB_LED, red, green, blue]))
    hid_reply = wait_for_response(beyond, [Hid_Message.SUCCESS, Hid_Message.ERROR])
    beyond.close()

    if(len(hid_reply) > 0):
        if(hid_reply[0] == Hid_Message.SUCCESS):
            return True
    return False


def wait_for_response(beyond: hid.device, message_types: list[int], timeout_ms: int = 100) -> bytes:
    start_time = time.monotonic_ns()

    while ((start_time + (timeout_ms * 1000000)) > time.monotonic_ns()):
        bytesout = beyond.read(65)
        if (len(bytesout) > 0):
            if (bytesout[0] in message_types):
                return bytes(bytesout)

    return b''