#
#   Imandra Inc.
#
#   speclogician/state/change_result.py
#

from __future__ import annotations

from typing import Literal, TypedDict, Union

from ..state.change import StateChange
from ..state.inst import StateInstance
from ..state.diff import StateDiff

class ProcessChangeError(TypedDict):
    ok: Literal[False]
    stage: Literal["apply_change", "analyze_change", "calc_diff", "refresh_stats", "trace_reachability"]
    error: Exception
    change: StateChange
    old_state: StateInstance

class ProcessChangeSuccess(TypedDict):
    ok: Literal[True]
    stage: Literal["ok"]
    change: StateChange
    old_state: StateInstance
    new_state: StateInstance
    state_diff: StateDiff | None # this is because it could potentially be the first state instance
    new_num_instances: int

ProcessChangeResult = Union[ProcessChangeError, ProcessChangeSuccess]


# ---------------------------------------------------------------------------
# Batch results
# ---------------------------------------------------------------------------

class ProcessBatchError(TypedDict):
    ok: Literal[False]
    stage: Literal["apply_change", "analyze_change", "calc_diff", "refresh_stats", "trace_reachability"]
    error: Exception
    changes: list[StateChange]
    change_index: int          # index of the failing change (-1 for post-apply stages)
    old_state: StateInstance

class ProcessBatchSuccess(TypedDict):
    ok: Literal[True]
    stage: Literal["ok"]
    changes: list[StateChange]
    old_state: StateInstance
    new_state: StateInstance
    state_diff: StateDiff | None
    new_num_instances: int

ProcessBatchResult = Union[ProcessBatchError, ProcessBatchSuccess]