#!/usr/bin/env python3
"""End-to-end pipeline test: episode -> breakdown -> manifest."""
import json
import sys
import tempfile
from pathlib import Path

RECOIL_ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(RECOIL_ROOT))


def test_full_pipeline():
    """Test the complete episode -> breakdown -> manifest pipeline."""
    project_path = RECOIL_ROOT.parent / 'projects' / 'afterimage'
    episode_path = project_path / 'episodes' / 'ep_01.md'

    if not episode_path.exists():
        print(f"FAIL: {episode_path} not found — run Phase 1 migration first")
        return False

    errors = []

    # 1. Verify episode is narrative-only (no PIPELINE DIRECTION)
    content = episode_path.read_text()
    if 'PIPELINE DIRECTION' in content:
        errors.append("Episode still contains PIPELINE DIRECTION section")

    # 2. Parse episode
    from visual.breakdown_agent import parse_episode_narrative, _stub_breakdown
    parsed = parse_episode_narrative(episode_path)

    if not parsed.get('episode_id'):
        errors.append("Failed to parse episode_id")
    if not parsed.get('beats'):
        errors.append("No beats parsed from episode")
    if not parsed.get('metadata'):
        errors.append("No metadata parsed from episode")

    print(f"  Parsed: {parsed['episode_id']}, {len(parsed.get('beats', []))} beats")

    # 3. Generate stub breakdown
    from visual.grammar_extractor import extract_grammar
    characters_md_path = project_path / 'bible' / 'characters.md'
    characters_md = characters_md_path.read_text() if characters_md_path.exists() else ''

    primary_char = ''
    for beat in parsed.get('beats', []):
        if beat.get('vo_character'):
            primary_char = beat['vo_character']
            break

    grammar = extract_grammar(characters_md, primary_char) if primary_char else {}
    breakdown = _stub_breakdown(parsed, grammar)

    if not breakdown.get('beats'):
        errors.append("Breakdown has no beats")
    if not breakdown.get('global_audio'):
        errors.append("Breakdown has no global_audio")

    # 4. Save and validate breakdown
    with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
        json.dump(breakdown, f, indent=2)
        breakdown_path = Path(f.name)

    from visual.validate_breakdown import validate_breakdown
    validation = validate_breakdown(breakdown_path)

    if not validation['valid']:
        errors.extend([f"Breakdown validation: {e}" for e in validation['errors']])

    print(f"  Breakdown: {validation['metrics'].get('total_shots', 0)} shots, valid={validation['valid']}")

    # 5. Compile manifest
    from visual.compiler import compile_from_breakdown

    # Use a temp project path for output
    with tempfile.TemporaryDirectory() as tmpdir:
        tmp_project = Path(tmpdir)
        manifest = compile_from_breakdown(breakdown_path, tmp_project, format_name='puzzle_box')

        if not manifest.get('tasks'):
            errors.append("Manifest has no tasks")

        # Check task types
        task_types = [t['type'] for t in manifest.get('tasks', [])]
        if 'image_generation' not in task_types:
            errors.append("Manifest missing image_generation tasks")

        print(f"  Manifest: {len(manifest.get('tasks', []))} tasks — {set(task_types)}")

    # Cleanup
    breakdown_path.unlink(missing_ok=True)

    # Report
    if errors:
        print(f"\nFAIL: {len(errors)} errors")
        for e in errors:
            print(f"  - {e}")
        return False
    else:
        print("\nPASS: Full pipeline works — episode -> breakdown -> manifest")
        return True


if __name__ == '__main__':
    success = test_full_pipeline()
    sys.exit(0 if success else 1)
