"""SoftwareInspect serial routing fixture, observed 2026-10-16.

Run with Python 3 from any directory. Prints the JSON published alongside this
file. Invented inputs and policy only; no CRM API, account execution, throughput,
concurrent updates, SLA performance, or customer outcomes are tested.
"""
import json
from collections import Counter

SOURCES = [
    "https://help.salesforce.com/s/articleView?id=service.creating_assignment_rules.htm&type=5",
    "https://knowledge.hubspot.com/workflows/assign-and-rotate-record-owners-using-workflows",
    "https://support.pipedrive.com/en/article/automatic-assignment",
]
REPS = {"Ava": {"active": True}, "Ben": {"active": True}, "Cy": {"active": False}}
POOLS = {("east", "core"): ["Ava", "Ben"], ("west", "core"): ["Ava"]}

def case(ident, lead, event, **extra):
    return dict(id=ident, lead=lead, event=event, purpose="sales", customer=False,
                current_owner=None, account_owners=[], territory="east", product="core", **extra)

# Explicit updates avoid hidden defaults when reading the published JSON.
INPUTS = [case("R01", "lead-1", "event-1"), case("R02", "lead-2", "event-2")]
for ident, changes in [
    ("R03", {"current_owner": "Ben"}),
    ("R04", {"current_owner": "Ben", "account_owners": ["Ava"]}),
    ("R05", {"account_owners": ["Ava"], "territory": "west"}),
    ("R06", {"current_owner": "Cy"}),
    ("R07", {"account_owners": ["Ava", "Ben"]}),
    ("R08", {"territory": None}),
    ("R09", {"territory": "west", "product": "specialty"}),
    ("R10", {"purpose": "support"}),
    ("R11", {"customer": True}),
]:
    item = case(ident, "lead-"+ident[1:].lstrip("0"), "event-"+ident[1:].lstrip("0"))
    item.update(changes)
    INPUTS.append(item)
INPUTS.append(case("R12", "lead-1", "event-1"))

def run():
    seen, owners, handoffs, rotation = set(), {}, set(), Counter()
    results = []
    for row in INPUTS:
        key = (row["lead"], row["event"])
        current = owners.get(row["lead"], row["current_owner"])
        task = False
        if key in seen:
            status, destination, reason = "suppressed", current, "duplicate_event"
        else:
            seen.add(key)
            matches = row["account_owners"]
            if row["purpose"] != "sales":
                status, destination, reason = "other_team", "support-intake", "non_sales"
            elif row["customer"]:
                status, destination, reason = "other_team", "customer-success", "existing_customer"
            elif len(matches) > 1:
                status, destination, reason = "review", "matching-review", "ambiguous_account"
            elif current and matches and current != matches[0]:
                status, destination, reason = "review", "ownership-review", "owner_conflict"
            elif current or matches:
                candidate = current or matches[0]
                if not REPS.get(candidate, {}).get("active"):
                    status, destination, reason = "review", "coverage-review", "inactive_owner"
                else:
                    status, destination = "sales", candidate
                    reason = "preserve_owner" if current else "account_owner"
            elif row["territory"] is None:
                status, destination, reason = "review", "data-review", "missing_territory"
            else:
                pool_key = (row["territory"], row["product"])
                pool = [p for p in POOLS.get(pool_key, []) if REPS[p]["active"]]
                if not pool:
                    status, destination, reason = "review", "coverage-review", "empty_eligible_pool"
                else:
                    destination = pool[rotation[pool_key] % len(pool)]
                    rotation[pool_key] += 1
                    status, reason = "sales", "pool_rotation"
            if status == "sales":
                owners[row["lead"]] = destination
                handoff_key = (row["lead"], "qualified-inbound-v1")
                task = handoff_key not in handoffs
                handoffs.add(handoff_key)
        results.append(dict(id=row["id"], status=status, destination=destination,
                            reason=reason, owner_after=owners.get(row["lead"], current),
                            create_sales_task=task))
    summary = dict(attempts=len(INPUTS), sales=sum(r["status"] == "sales" for r in results),
                   review=sum(r["status"] == "review" for r in results),
                   other_team=sum(r["status"] == "other_team" for r in results),
                   suppressed=sum(r["status"] == "suppressed" for r in results),
                   sales_tasks=sum(r["create_sales_task"] for r in results))
    assert [r["destination"] for r in results] == [
        "Ava", "Ben", "Ben", "ownership-review", "Ava", "coverage-review",
        "matching-review", "data-review", "coverage-review", "support-intake",
        "customer-success", "Ava"]
    assert results[3]["owner_after"] == "Ben"
    assert summary == dict(attempts=12, sales=4, review=5, other_team=2, suppressed=1, sales_tasks=4)
    return dict(date="2026-10-16", author="SoftwareInspect Team",
                method="Sequential Python policy fixture with 12 invented attempts. Owner conflicts retain the current CRM owner; review destination is a separate operational field. Rotation advances only for eligible new pool assignments.",
                limitations="Not a vendor implementation or customer test. No concurrent writes, real identity matching, permissions, availability schedules, delivery, or response-time outcomes tested. Active named owners bypass territory/product pools by explicit example policy; real teams must approve coverage and specialist handoffs.",
                sources=SOURCES, reps=REPS,
                pools=[dict(territory=k[0], product=k[1], reps=v) for k,v in POOLS.items()],
                inputs=INPUTS, results=results, summary=summary)

if __name__ == "__main__":
    print(json.dumps(run(), indent=2))
