#!/usr/bin/env python3
"""Validate plan links/contracts only. Does not run Docker, Java, Gradle or devices."""
import ast
import csv
import json
from pathlib import Path
import re

root = Path(__file__).resolve().parents[1]
required = ['START_HERE.md', 'contracts.md', 'implementation-plan.md', 'summary.md',
            'sdk-change-contract.md', 'tasks.csv', 'test-matrix.csv', 'source-index.csv',
            'review-decision.json', 'preflight-result.json', 'docker/README.md',
            'docker/Dockerfile.jdk8', 'docker/Dockerfile.jdk17', 'docker/run.sh',
            'docker/toolchain-lock.json']
for name in required:
    assert (root / name).is_file(), name
for path in root.rglob('*.py'):
    ast.parse(path.read_text(encoding='utf-8'), filename=str(path))
for path in root.rglob('*.json'):
    json.loads(path.read_text(encoding='utf-8'))


def read_csv(name):
    with (root / name).open(encoding='utf-8', newline='') as stream:
        return list(csv.DictReader(stream))


tasks = read_csv('tasks.csv')
tests = read_csv('test-matrix.csv')
by_task = {x['task_id']: x for x in tasks}
by_test = {x['test_id']: x for x in tests}
assert len(by_task) == len(tasks)
assert len(by_test) == len(tests)
for task in tasks:
    assert task['execution_status'] == 'PENDING_REVIEW'
    for dep in filter(None, task['depends_on'].split(';')):
        assert dep in by_task, (task['task_id'], dep)
    for test in task['test_ids'].split(';'):
        assert test in by_test and by_test[test]['task_id'] == task['task_id'], test
for test in tests:
    assert test['task_id'] in by_task
    assert all(test[key] for key in ['given', 'when', 'then', 'suite_or_entry'])
visited, visiting = set(), set()


def visit(name):
    assert name not in visiting, 'Cyclic task dependency: ' + name
    if name in visited:
        return
    visiting.add(name)
    for dep in filter(None, by_task[name]['depends_on'].split(';')):
        visit(dep)
    visiting.remove(name)
    visited.add(name)


for name in by_task:
    visit(name)
for path in root.glob('*.md'):
    for target in re.findall(r'\]\(([^)]+)\)', path.read_text(encoding='utf-8')):
        if target.startswith(('https:', 'http:', '#')):
            continue
        local = target.split('#', 1)[0]
        assert (path.parent / local).exists(), (path.name, local)
decision = json.loads((root / 'review-decision.json').read_text())
assert decision['status'] == 'PENDING_REVIEW' and decision['approval_evidence'] is None
preflight = json.loads((root / 'preflight-result.json').read_text())
assert preflight['inventory']['host_jdk_used'] is False
assert preflight['inventory']['host_android_sdk_used'] is False
assert 'weightAvailable' in (root / 'contracts.md').read_text()
assert 'fromError' in (root / 'contracts.md').read_text()
assert 'handleWeightObservation(observation)' in (root / 'implementation-plan.md').read_text()
print(json.dumps({'plan_validation': 'PASS', 'tasks': len(tasks), 'test_oracles': len(tests),
                  'dependency_graph': 'ACYCLIC', 'review': decision['status'],
                  'runtime_execution': 'NOT_PERFORMED',
                  'boundary': 'Structural checks, not implementation or Docker validation'}, indent=2))
