# /// script
# requires-python = ">=3.10"
# ///
# Copyright (c) 2026 Aayush Sharma · SPDX-License-Identifier: MIT
# https://thedataengineering.com/lab-code/LICENSE.txt
"""The false-alarm floor of a referential-integrity check.

Customers load every L minutes, orders every 10 minutes; 2% of orders come
from customers who signed up less than 60 minutes earlier. At each order
batch, count orders whose customer is not loaded yet ("orphans"), for L from
5 to 120 minutes. Then allow lateness: check only orders older than L + 10.
"""
import argparse, json, random

p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
p.add_argument("--days", type=int, default=7, help="Simulated days.")
p.add_argument("--orders-per-min", type=float, default=50, help="Orders per minute.")
p.add_argument("--new-share", type=float, default=0.02, help="Share of orders from customers who signed up in the last hour.")
p.add_argument("--loads", type=lambda s: [int(v) for v in s.split(",")], default=[5, 15, 30, 60, 120], help="Customer load intervals L, minutes.")
p.add_argument("--seed", type=int, default=0, help="Random seed.")
p.add_argument("--json", help="Also write the results to this JSON file.")
args = p.parse_args()
random.seed(args.seed)
minutes = args.days * 1440

orders = []                                                 # (order time, customer signup time)
for m in range(minutes):
    for _ in range(int(args.orders_per_min)):
        t = m + random.random()
        signup = t - random.uniform(0, 60) if random.random() < args.new_share else t - random.uniform(60, 60 * 24 * 365)
        orders.append((t, signup))

rows = []
for L in args.loads:
    alarms = checked = alarms_late = checked_late = 0
    for t, signup in orders:
        batch_at = (int(t // 10) + 1) * 10                 # the order arrives with the next 10-minute batch
        loaded_until = (batch_at // L) * L                  # customers loaded as of the last customer load
        checked += 1; alarms += signup > loaded_until
        if batch_at - t >= 0:                               # allowed lateness: check the order once it is L + 10 old
            check_at = t + L + 10
            loaded_then = (check_at // L) * L
            checked_late += 1; alarms_late += signup > loaded_then
    rows.append({"L": L, "false_alarm_pct": alarms / checked * 100, "with_lateness_pct": alarms_late / checked_late * 100})
    print(f"customers every {L:>3} min: {alarms / checked:6.3%} of orders look orphaned   "
          f"with lateness L + 10: {alarms_late / checked_late:6.3%}")

if args.json:
    with open(args.json, "w") as f:
        json.dump({"tables": {"loads": rows}}, f)
