"""Owon PSU quick demo (optimized to use ecu_framework.power.owon_psu).

This script reads configuration from OWON_PSU_CONFIG (YAML) or ./config/owon_psu.yaml,
prints discovered ports responding to *IDN?, then connects to the configured port
and performs a small sequence (IDN, optional V/I set, toggle output, measure V/I).

No CLI flags; edit YAML to change behavior.
"""

from __future__ import annotations

import os
import time
from pathlib import Path

import yaml

try:
    from ecu_framework.power import OwonPSU, SerialParams, scan_ports
except ModuleNotFoundError:
    # Ensure repository root is on sys.path when running this file directly
    import sys
    repo_root = Path(__file__).resolve().parents[2]
    if str(repo_root) not in sys.path:
        sys.path.insert(0, str(repo_root))
    from ecu_framework.power import OwonPSU, SerialParams, scan_ports


def _load_yaml_config() -> dict:
    cfg_path = str(Path("config") / "owon_psu.yaml")
    p = Path(cfg_path).resolve()  
    print("Using config path:", str(p))
    if not p.is_file():
        return {}
    with p.open("r", encoding="utf-8") as f:
        data = yaml.safe_load(f) or {}
        return data if isinstance(data, dict) else {}


def run_demo() -> int:
    cfg = _load_yaml_config()
    if not cfg or "port" not in cfg:
        print("Config not found or missing 'port'. Set OWON_PSU_CONFIG or create ./config/owon_psu.yaml")
        return 2

    print("Scanning ports (responding to *IDN?):")
    for dev, idn in scan_ports(SerialParams(baudrate=int(cfg.get("baudrate", 115200)), timeout=float(cfg.get("timeout", 1.0)))):
        print(f"  {dev} -> {idn}")

    # Serial params
    baud = int(cfg.get("baudrate", 115200))
    timeout = float(cfg.get("timeout", 1.0))
    eol = cfg.get("eol", "\n")
    from serial import PARITY_NONE, PARITY_EVEN, PARITY_ODD, STOPBITS_ONE, STOPBITS_TWO
    parity = {"N": PARITY_NONE, "E": PARITY_EVEN, "O": PARITY_ODD}.get(str(cfg.get("parity", "N")).upper(), PARITY_NONE)
    stopbits = {1: STOPBITS_ONE, 2: STOPBITS_TWO}.get(int(float(cfg.get("stopbits", 1))), STOPBITS_ONE)
    xonxoff = bool(cfg.get("xonxoff", False))
    rtscts = bool(cfg.get("rtscts", False))
    dsrdtr = bool(cfg.get("dsrdtr", False))

    ps = SerialParams(
        baudrate=baud,
        timeout=timeout,
        parity=parity,
        stopbits=stopbits,
        xonxoff=xonxoff,
        rtscts=rtscts,
        dsrdtr=dsrdtr,
    )

    port = str(cfg["port"]).strip()

    do_set = bool(cfg.get("do_set", False))
    set_v = float(cfg.get("set_voltage", 1.0))
    set_i = float(cfg.get("set_current", 0.1))

    with OwonPSU(port, ps, eol=eol) as psu:
        idn = psu.idn()
        print(f"IDN: {idn}")
        print(f"Output status: {psu.output_status()}")
        if do_set:
            # psu.set_output(True)
            time.sleep(0.8)
            psu.set_voltage(1, set_v)
            psu.set_current(1, set_i)
            time.sleep(0.75)
            print(f"Measured V: {psu.measure_voltage()} V")
            print(f"Measured I: {psu.measure_current()} A")
            time.sleep(0.5)
            # psu.set_output(False)
    return 0


if __name__ == "__main__":
    raise SystemExit(run_demo())
