#
#   Imandra Inc.
#
#   speclogician/modeling/spec_stats.py
#


from __future__ import annotations

from speclogician.data.mapping import ArtifactMap
from speclogician.modeling.conflict import ScenarioConsumed, ScenarioOverlap
from speclogician.modeling.scenario import Inconsistent, Missing
from speclogician.modeling.spec import Spec


def refresh_spec_stats(spec: Spec, *, art_map: ArtifactMap | None) -> None:
    # ---- scenarios ----
    spec.num_sc_total = len(spec.scenarios)

    spec.num_sc_missing = sum(
        1 for sc in spec.scenarios if isinstance(getattr(sc, "component_status", None), Missing)
    )
    spec.num_sc_inconsistent = sum(
        1 for sc in spec.scenarios if isinstance(getattr(sc, "component_status", None), Inconsistent)
    )

    # "matched" should be keyed by scenario.comp_id (NOT name)
    if art_map is None:
        spec.num_sc_matched = 0
    else:
        comp_to_art = getattr(art_map, "comp_to_art_map", {}) or {}
        spec.num_sc_matched = sum(
            1 for sc in spec.scenarios if len(comp_to_art.get(sc.comp_id, [])) > 0
        )

    # ---- conflicts (spec-level) ----
    spec.num_sc_conflicted = len(spec.scenario_conflicts or [])
    spec.num_sc_overlap = sum(isinstance(c, ScenarioOverlap) for c in (spec.scenario_conflicts or []))
    spec.num_sc_consumed = sum(isinstance(c, ScenarioConsumed) for c in (spec.scenario_conflicts or []))

    # ---- predicates / transitions matched (linked to at least one artifact) ----
    dm = spec.domain_model
    if art_map is None:
        dm.num_state_preds_matched = 0
        dm.num_action_preds_matched = 0
        dm.num_trans_matched = 0
    else:
        comp_to_art = getattr(art_map, "comp_to_art_map", {}) or {}
        dm.num_state_preds_matched = sum(
            1 for p in dm.state_preds if len(comp_to_art.get(p.name, [])) > 0
        )
        dm.num_action_preds_matched = sum(
            1 for p in dm.action_preds if len(comp_to_art.get(p.name, [])) > 0
        )
        dm.num_trans_matched = sum(
            1 for t in dm.transitions if len(comp_to_art.get(t.name, [])) > 0
        )
    dm.num_preds_matched = dm.num_state_preds_matched + dm.num_action_preds_matched
