"""Generate public-safe packaging, test, and reliability teaching datasets.

The generated files are conceptual, precomputed replays for SemiAgora pages.
They avoid product package design, ATE programs, qualification signoff,
JEDEC release claims, customer quality statements, and production workflows.
"""

from __future__ import annotations

import json
from pathlib import Path


ROOT = Path(__file__).resolve().parent


SOURCES = [
    {
        "label": "NIST National Advanced Packaging Manufacturing Program",
        "url": "https://www.nist.gov/chips/research-development-programs/national-advanced-packaging-manufacturing-program",
        "note": "Public NIST page framing advanced packaging challenges around power, heat, test, repair, and reliability.",
    },
    {
        "label": "NIST advanced semiconductor packaging material needs",
        "url": "https://www.nist.gov/publications/material-needs-and-measurement-challenges-advanced-semiconductor-packaging",
        "note": "Public NIST publication page on packaging materials, metrology, moisture reliability, residual stress, warpage, and reproducibility.",
    },
    {
        "label": "NIST reliability metrology for semiconductors",
        "url": "https://www.nist.gov/publications/reliability-metrology-semiconductor-industry-nist",
        "note": "Public NIST publication page anchoring reliability assessment as a semiconductor metrology concern.",
    },
    {
        "label": "SEMI Heterogeneous Integration Roadmap",
        "url": "https://www.semi.org/en/communities/heterogeneous_integration_roadmap",
        "note": "Public roadmap page connecting assembly, packaging, interconnect, test, thermal management, and reliability.",
    },
]


LIMITS = [
    "No product package design, package signoff, board design release, or production thermal-design decision is included.",
    "No ATE program, wafer-sort recipe, bin-limit release, test-time quote, or production screen is included.",
    "No JEDEC qualification, customer quality claim, reliability signoff, or device release statement is made.",
    "All numbers are educational teaching proxies and must be replaced by qualified measurements before engineering decisions.",
]


def write_json(filename: str, payload: dict) -> None:
    (ROOT / filename).write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")


def monotonic_decrease(values: list[float]) -> bool:
    return all(values[i] >= values[i + 1] for i in range(len(values) - 1))


def monotonic_increase(values: list[float]) -> bool:
    return all(values[i] <= values[i + 1] for i in range(len(values) - 1))


def common_payload(experiment_id: str, title: str, model_boundary: str) -> dict:
    return {
        "schema": "semiagora.ptr-simulation.v1",
        "experiment_id": experiment_id,
        "title": title,
        "execution_mode": "precomputed-only",
        "model_boundary": model_boundary,
        "limitations": LIMITS,
        "sources": SOURCES,
    }


def package_parasitics() -> None:
    cases = [
        {
            "label": "wirebond_qfn_teaching_case",
            "interconnect_length_mm": 4.0,
            "loop_inductance_pH": 3200,
            "coupling_capacitance_fF": 110,
            "signal_delay_ps": 22,
            "pdn_impedance_mOhm": 180,
        },
        {
            "label": "flip_chip_bga_teaching_case",
            "interconnect_length_mm": 1.2,
            "loop_inductance_pH": 520,
            "coupling_capacitance_fF": 180,
            "signal_delay_ps": 11,
            "pdn_impedance_mOhm": 92,
        },
        {
            "label": "interposer_2p5d_teaching_case",
            "interconnect_length_mm": 0.45,
            "loop_inductance_pH": 180,
            "coupling_capacitance_fF": 260,
            "signal_delay_ps": 7,
            "pdn_impedance_mOhm": 55,
        },
        {
            "label": "chiplet_3d_teaching_case",
            "interconnect_length_mm": 0.12,
            "loop_inductance_pH": 80,
            "coupling_capacitance_fF": 420,
            "signal_delay_ps": 5,
            "pdn_impedance_mOhm": 38,
        },
    ]
    inductance = [case["loop_inductance_pH"] for case in cases]
    delay = [case["signal_delay_ps"] for case in cases]
    pdn = [case["pdn_impedance_mOhm"] for case in cases]
    payload = common_payload(
        "SA-PTR-PKG-PARASITICS-001",
        "Package parasitics RLC budget",
        "Educational package-parasitics replay for trend literacy; not a package extraction, package design, or signal/power-integrity signoff model.",
    )
    payload.update(
        {
            "axes": ["package integration teaching case"],
            "cases": cases,
            "derived_metrics": {
                "interposer_inductance_pH": cases[2]["loop_inductance_pH"],
                "chiplet_3d_signal_delay_ps": cases[3]["signal_delay_ps"],
                "wirebond_to_3d_inductance_reduction_percent": round(
                    100 * (1 - cases[3]["loop_inductance_pH"] / cases[0]["loop_inductance_pH"]), 2
                ),
            },
            "verification": {
                "case_count": len(cases),
                "inductance_decreases_with_integration": monotonic_decrease(inductance),
                "signal_delay_decreases": monotonic_decrease(delay),
                "pdn_impedance_decreases": monotonic_decrease(pdn),
                "all_cases_precomputed": True,
            },
        }
    )
    write_json("ptr-package-parasitics-rlc-web-v1.json", payload)


def thermal_stack() -> None:
    cases = [
        {
            "label": "wirebond_plastic_package",
            "theta_junction_to_case_c_per_w": 9,
            "theta_case_to_ambient_c_per_w": 29,
            "hotspot_coupling_index": 0.18,
        },
        {
            "label": "flip_chip_bga_heat_spreader",
            "theta_junction_to_case_c_per_w": 4,
            "theta_case_to_ambient_c_per_w": 18,
            "hotspot_coupling_index": 0.22,
        },
        {
            "label": "interposer_lid_2p5d",
            "theta_junction_to_case_c_per_w": 3,
            "theta_case_to_ambient_c_per_w": 12,
            "hotspot_coupling_index": 0.34,
        },
        {
            "label": "stacked_3d_hotspot_case",
            "theta_junction_to_case_c_per_w": 5,
            "theta_case_to_ambient_c_per_w": 13,
            "hotspot_coupling_index": 0.72,
        },
    ]
    for case in cases:
        total = case["theta_junction_to_case_c_per_w"] + case["theta_case_to_ambient_c_per_w"]
        case["theta_ja_c_per_w"] = total
        case["max_power_for_60c_rise_w"] = round(60 / total, 2)
    payload = common_payload(
        "SA-PTR-THERMAL-STACK-001",
        "Package thermal resistance stack",
        "Educational thermal-resistance replay for trend literacy; not a calibrated thermal model, package qualification, or heat-sink recommendation.",
    )
    payload.update(
        {
            "axes": ["package thermal teaching case"],
            "cases": cases,
            "derived_metrics": {
                "lowest_theta_case": "interposer_lid_2p5d",
                "lowest_theta_ja_c_per_w": 15,
                "stacked_3d_hotspot_index": 0.72,
                "wirebond_max_power_for_60c_rise_w": cases[0]["max_power_for_60c_rise_w"],
            },
            "verification": {
                "case_count": len(cases),
                "totals_match_series_sum": all(
                    case["theta_ja_c_per_w"]
                    == case["theta_junction_to_case_c_per_w"] + case["theta_case_to_ambient_c_per_w"]
                    for case in cases
                ),
                "two_point_five_d_lowest_total": min(cases, key=lambda x: x["theta_ja_c_per_w"])["label"]
                == "interposer_lid_2p5d",
                "hotspot_risk_increases_for_3d": cases[-1]["hotspot_coupling_index"] > cases[-2]["hotspot_coupling_index"],
            },
        }
    )
    write_json("ptr-thermal-resistance-stack-web-v1.json", payload)


def wafer_sort() -> None:
    cases = [
        {
            "label": "minimal_guardband",
            "effective_yield_percent": 88,
            "top_bin_percent": 18,
            "estimated_escape_ppm": 3800,
            "retest_percent": 0.9,
        },
        {
            "label": "balanced_guardband",
            "effective_yield_percent": 83,
            "top_bin_percent": 15,
            "estimated_escape_ppm": 900,
            "retest_percent": 2.1,
        },
        {
            "label": "aggressive_guardband",
            "effective_yield_percent": 76,
            "top_bin_percent": 11,
            "estimated_escape_ppm": 300,
            "retest_percent": 4.2,
        },
    ]
    payload = common_payload(
        "SA-PTR-TEST-WAFER-SORT-001",
        "Wafer sort binning and guardband",
        "Educational wafer-sort guardband replay for test-yield tradeoff literacy; not an ATE program, production screen, or bin-limit release.",
    )
    payload.update(
        {
            "axes": ["guardband policy teaching case"],
            "cases": cases,
            "derived_metrics": {
                "yield_loss_minimal_to_aggressive_percent": cases[0]["effective_yield_percent"]
                - cases[-1]["effective_yield_percent"],
                "escape_reduction_minimal_to_balanced_ppm": cases[0]["estimated_escape_ppm"]
                - cases[1]["estimated_escape_ppm"],
                "balanced_retest_percent": cases[1]["retest_percent"],
            },
            "verification": {
                "case_count": len(cases),
                "yield_decreases_with_guardband": monotonic_decrease(
                    [case["effective_yield_percent"] for case in cases]
                ),
                "escape_ppm_decreases_with_guardband": monotonic_decrease(
                    [case["estimated_escape_ppm"] for case in cases]
                ),
                "retest_increases_with_guardband": monotonic_increase([case["retest_percent"] for case in cases]),
                "all_cases_precomputed": True,
            },
        }
    )
    write_json("ptr-wafer-sort-binning-yield-web-v1.json", payload)


def reliability_bathtub() -> None:
    time_hours = [1, 10, 100, 1000, 10000, 50000]
    failure_rate_fit = [120, 45, 12, 8, 8, 24]
    samples = [
        {"time_hours": t, "failure_rate_fit": fit}
        for t, fit in zip(time_hours, failure_rate_fit)
    ]
    stress_modes = [
        {
            "label": "high_temperature_operating_life",
            "acceleration_proxy": 0.92,
            "screens": "bias and temperature driven wear mechanisms",
        },
        {
            "label": "temperature_cycling",
            "acceleration_proxy": 0.84,
            "screens": "package, board, and material mismatch fatigue",
        },
        {
            "label": "high_humidity_bias",
            "acceleration_proxy": 0.71,
            "screens": "moisture, leakage, and corrosion sensitivity",
        },
        {
            "label": "board_level_drop_or_bend_proxy",
            "acceleration_proxy": 0.63,
            "screens": "mechanical and assembly-related weakness",
        },
    ]
    payload = common_payload(
        "SA-PTR-REL-STRESS-BATHTUB-001",
        "Reliability stress and bathtub curve",
        "Educational reliability-stress replay for vocabulary and trend literacy; not a JEDEC qualification plan, FIT prediction, or product release claim.",
    )
    payload.update(
        {
            "axes": ["time in service teaching point", "stress-mode vocabulary"],
            "samples": samples,
            "stress_modes": stress_modes,
            "derived_metrics": {
                "infant_mortality_drop_fit": failure_rate_fit[0] - failure_rate_fit[2],
                "useful_life_fit": failure_rate_fit[3],
                "wearout_rise_fit": failure_rate_fit[-1] - failure_rate_fit[-2],
                "stress_mode_count": len(stress_modes),
            },
            "verification": {
                "sample_count": len(samples),
                "infant_mortality_decreases": failure_rate_fit[0] > failure_rate_fit[1] > failure_rate_fit[2],
                "useful_life_flat": failure_rate_fit[3] == failure_rate_fit[4],
                "wearout_increases": failure_rate_fit[-1] > failure_rate_fit[-2],
                "stress_mode_count": len(stress_modes),
            },
        }
    )
    write_json("ptr-accelerated-stress-bathtub-web-v1.json", payload)


def main() -> None:
    package_parasitics()
    thermal_stack()
    wafer_sort()
    reliability_bathtub()


if __name__ == "__main__":
    main()
