"""
Pipeline consistency validation for V5 orchestrator.

Checks that an iteration's based_on matches the current pipeline state.
"""

import json
from pathlib import Path

from .iteration import read_metadata
from .pipeline import STAGE_DEPENDENCIES, PIPELINE_STAGES


def validate_selection(
    take_path: Path,
    stage: str,
    iteration: str,
    pipeline: dict,
) -> tuple:
    """
    Check if iteration's based_on matches pipeline's parent selections.

    Args:
        take_path: Path to take directory
        stage: Stage name
        iteration: Iteration number
        pipeline: Current pipeline state

    Returns:
        (is_consistent, warnings) where warnings is a list of strings
    """
    iter_dir = take_path / stage / iteration
    meta = read_metadata(iter_dir)

    if not meta:
        return False, [f"No metadata.json found in {stage}/{iteration}"]

    based_on = meta.get("based_on", {})
    parent_deps = STAGE_DEPENDENCIES.get(stage, [])
    warnings = []

    for parent_stage in parent_deps:
        expected = pipeline.get(parent_stage)
        actual = based_on.get(parent_stage)

        if expected != actual:
            warnings.append(
                f"  {parent_stage}: iteration based on {actual}, "
                f"pipeline has {expected}"
            )

    return len(warnings) == 0, warnings


def find_invalidated_downstream(
    take_path: Path,
    stage: str,
    new_iteration: str,
    pipeline: dict,
) -> list:
    """
    Find downstream stages whose selected iterations were based on
    a different iteration of this stage.

    Returns list of (stage_name, issue_description) tuples.
    """
    invalidated = []
    stage_idx = PIPELINE_STAGES.index(stage) if stage in PIPELINE_STAGES else -1

    for ds in PIPELINE_STAGES[stage_idx + 1:]:
        ds_iter = pipeline.get(ds)
        if ds_iter is None:
            continue

        # Check if this downstream stage depends on our stage
        deps = STAGE_DEPENDENCIES.get(ds, [])
        if stage not in deps:
            continue

        ds_meta = read_metadata(take_path / ds / ds_iter)
        ds_based_on = ds_meta.get("based_on", {})

        if stage in ds_based_on and ds_based_on[stage] != new_iteration:
            invalidated.append((
                ds,
                f"based on {stage}/{ds_based_on[stage]}, "
                f"now selecting {stage}/{new_iteration}"
            ))

    return invalidated
