"""
In-memory stand-in for the NB client in netbox/dc-rack-mgmt-import.py.

No real NetBox / network access exists this session -- this fake implements just
the two methods the target script calls on its client (.one() and .create()) so the
REAL main()/preflight can be driven end-to-end without a live server. It is injected
at the get_nb() seam, exactly as tests/dc-edge-wan-import/ injects its fake.

FIDELITY NOTE. The target's real .one() issues GET ...?<filter>&limit=1 and takes
results[0] -- so it is single-match by construction and CANNOT raise on a duplicate
(unlike pynetbox.get(), which the older sibling fake models raising on multi-match).
This fake matches THAT contract: .one() returns the first record whose fields equal
the filter, or None. For an idempotency SKIP that is the safe direction -- a
pre-existing object reads as "present" and is not duplicated. .create() records every
write so a test can assert a rejected/dry run wrote NOTHING. The store is keyed by
path, so ipam/prefixes, ipam/roles, dcim/sites AND ipam/ip-addresses all work.
"""
from __future__ import annotations


class FakeNB:
    def __init__(self, roles=(), prefixes=(), sites=(), ip_addresses=()):
        # store: endpoint path -> list of record dicts (as the API would return them)
        self.store = {
            "ipam/roles": [dict(r) for r in roles],
            "ipam/prefixes": [dict(p) for p in prefixes],
            "dcim/sites": [dict(s) for s in sites],
            "ipam/ip-addresses": [dict(a) for a in ip_addresses],
        }
        self.creates = []   # (path, payload) for every .create() -- the write ledger
        self._next_id = 1000

    def one(self, path, **flt):
        for rec in self.store.get(path, []):
            if all(str(rec.get(k)) == str(v) for k, v in flt.items()):
                return rec
        return None

    def create(self, path, payload):
        self.creates.append((path, dict(payload)))
        rec = dict(payload)
        rec["id"] = self._next_id
        self._next_id += 1
        self.store.setdefault(path, []).append(rec)
        return rec
