"""Wishbone protocol decoder."""

from __future__ import annotations
from dataclasses import dataclass


@dataclass
class WishboneTxn:
    addr: int
    data: int
    write: bool
    start: int
    end: int


class Wishbone:
    """Wishbone B4 protocol decoder."""

    @staticmethod
    def bind(**signals) -> "BoundWishbone":
        return BoundWishbone(signals)


class BoundWishbone:
    def __init__(self, signals: dict):
        self.signals = signals
        self._trace = None
        for sig in signals.values():
            if hasattr(sig, "_trace"):
                self._trace = sig._trace
                break

    def _val(self, name, index):
        sig = self.signals.get(name)
        if sig is None:
            return None
        old = self._trace._index
        self._trace._index = index
        self._trace._virtual_cache.clear()
        v = sig.value
        self._trace._index = old
        return v

    def transactions(self) -> list[WishboneTxn]:
        """Extract Wishbone transactions (CYC & STB & ACK)."""
        t = self._trace
        if t is None:
            return []

        cyc = self.signals.get("cyc")
        stb = self.signals.get("stb")
        ack = self.signals.get("ack")
        if not all([cyc, stb, ack]):
            return []

        hs_indices = t.find(cyc & stb & ack)
        results = []

        for idx in hs_indices:
            addr = self._val("adr", idx) or 0
            we = self._val("we", idx)
            is_write = bool(we)
            data = self._val("dat_w" if is_write else "dat_r", idx) or 0

            results.append(WishboneTxn(
                addr=addr, data=data, write=is_write,
                start=idx, end=idx,
            ))

        return results
