import os
import asyncio
import logging as log

async def reset_nrf54l(interface: int = 0, timeout: float = 8.0):
    """
    Reset the nRF54L target using OpenOCD before starting broadcast.

    Looks for interface config files in the project at `src/openocd/` relative to this module only.
    Accepts filename variants per slot:
      - slot 0: raspberrypi-swd0.cfg or swd0.cfg
      - slot 1: raspberrypi-swd1.cfg or swd1.cfg

    Executes the equivalent of:
        openocd \
          -f ./raspberrypi-${INTERFACE}.cfg \
          -f target/nordic/nrf54l.cfg \
          -c "init" \
          -c "reset run" \
          -c "shutdown"

    Best-effort: if OpenOCD is unavailable, logs a warning and continues.
    """
    try:
        # Resolve project directory and filenames
        proj_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'openocd'))
        names = ['raspberrypi-swd0.cfg', 'swd0.cfg'] if interface == 0 else ['raspberrypi-swd1.cfg', 'swd1.cfg']
        cfg = None
        for n in names:
            p = os.path.join(proj_dir, n)
            if os.path.exists(p):
                cfg = p
                break
        if not cfg:
            log.warning("reset_nrf54l: no interface CFG found in project dir %s; skipping reset", proj_dir)
            return

        # Build openocd command (no sudo required as per project setup).
        cmd = ['openocd', '-f', cfg, '-f', 'target/nordic/nrf54l.cfg',
               '-c', 'init', '-c', 'reset run', '-c', 'shutdown']
        async def _run(cmd):
            proc = await asyncio.create_subprocess_exec(
                *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT
            )
            try:
                out, _ = await asyncio.wait_for(proc.communicate(), timeout=timeout)
            except asyncio.TimeoutError:
                log.error("reset_nrf54l: %s timed out; terminating", cmd[0])
                proc.kill()
                return False
            rc = proc.returncode
            if rc != 0:
                log.error("reset_nrf54l: %s exited with code %s; output: %s", cmd[0], rc, (out or b'').decode(errors='ignore'))
                return False
            return True

        ok = await _run(cmd)
        if ok:
            log.info("reset_nrf54l: reset succeeded (interface %d) using %s", interface, cfg)

    except FileNotFoundError:
        log.error("reset_nrf54l: openocd not found; skipping reset")
    except Exception:
        log.error("reset_nrf54l failed", exc_info=True)


if __name__ == '__main__':
    # Basic logging setup
    log.basicConfig(
        level=os.environ.get('LOG_LEVEL', log.INFO),
        format='%(asctime)s.%(msecs)03d %(levelname)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )
    interface_to_reset = 0
    log.info(f"Executing reset for interface {interface_to_reset}")
    asyncio.run(reset_nrf54l(interface=interface_to_reset))

    interface_to_reset = 1
    log.info(f"Executing reset for interface {interface_to_reset}")
    asyncio.run(reset_nrf54l(interface=interface_to_reset))
