import time
import subprocess
import serial
from serial.tools import list_ports
from serial import SerialException

# ===== Detect Arduino port =====
def find_arduino_port():
    for port in list_ports.comports():
        if any(keyword in port.description for keyword in ['Arduino', 'ttyACM', 'usbmodem']):
            return port.device
    return None

# ===== Upload Arduino code =====
def upload_arduino_code(upload_script_path: str):
    print(f"🔄 Running upload script: {upload_script_path}")
    
    process = subprocess.Popen(
        [upload_script_path],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True
    )

    while True:
        line = process.stdout.readline()
        if not line and process.poll() is not None:
            break
        if line:
            print(line.strip())

    return_code = process.poll()
    if return_code != 0:
        print(f"❌ Upload script exited with code {return_code}")
        return False

    return True

# ===== Open serial port and wait for ARDUINO_READY =====
def open_arduino_port(port: str, baudrate: int = 9600, timeout: int = 5):
    try:
        ser = serial.Serial(port, baudrate, timeout=timeout)
        print("⏳ Waiting for ARDUINO_READY...")
        start = time.time()
        while time.time() - start < timeout:
            line = ser.readline().decode().strip()
            if line == "ARDUINO_READY":
                print("✅ Arduino is ready!")
                return ser
        print("⚠️ ARDUINO_READY not received in time")
        return None
    except Exception as e:
        print(f"❌ Failed to open serial port: {e}")
        return None

# ===== Read light sensor from an already opened serial port =====
def read_light_sensor(ser, timeout: int = 2):
    """Send READ_LIGHT and return the value, non-blocking except for timeout."""
    try:
        ser.reset_input_buffer()  # clear any old data
        ser.write(b"READ_LIGHT\n")
        start = time.time()
        while time.time() - start < timeout:
            line = ser.readline().decode().strip()
            if line:
                try:
                    return int(line)
                except ValueError:
                    continue
        print("⚠️ No sensor value received")
        return None
    except (OSError, SerialException) as e:
        print(f"❌ Serial error: {e}")
        return None