"""Count an author-designed survey fixture; validate structured count claims.

Standard library only. Does not call Google, a model, or any network service.
It checks arithmetic and explicit denominators, not the meaning of free text.
"""
from collections import Counter
from pathlib import Path
import argparse
import hashlib
import json

OPTIONS = ('Clear steps', 'Reusable files', 'Video walkthrough')


def reference(data):
    assert data['kind'] == 'author_constructed_fictional_fixture'
    assert data['real_respondents'] is False
    rows = data['rows']
    assert rows and len({r['id'] for r in rows}) == len(rows)
    assert all(r['context'] in ('Solo', 'Team') for r in rows)
    assert all(isinstance(r['comment'], str) for r in rows)
    assert all(len(r['improvements']) == len(set(r['improvements'])) and set(r['improvements']).issubset(OPTIONS) for r in rows)
    counts = Counter(o for r in rows for o in r['improvements'])
    answered = sum(bool(r['improvements']) for r in rows)
    return {
        'kind': 'deterministic_counts_of_fictional_fixture',
        'real_respondents': False,
        'total_rows': len(rows),
        'choice_answered_rows': answered,
        'choice_blank_rows': len(rows) - answered,
        'comment_nonblank_rows': sum(bool(r['comment'].strip()) for r in rows),
        'selection_count': sum(counts.values()),
        'choice_is_multi_select': True,
        'options': {o: {'count': counts[o], 'percent_of_all_rows': round(counts[o] / len(rows) * 100, 1), 'percent_of_answered_rows': round(counts[o] / answered * 100, 1) if answered else None} for o in OPTIONS},
        'contexts': {g: {'total_rows': sum(r['context'] == g for r in rows), 'choice_answered_rows': sum(r['context'] == g and bool(r['improvements']) for r in rows), 'option_counts': dict(Counter(o for r in rows if r['context'] == g for o in r['improvements']))} for g in ('Solo', 'Team')},
        'limits': 'Arithmetic reference only. No real survey demand, population inference, causality, text-topic classification, model benchmark, or measured time saving.'
    }


def claim_issues(claim, counts):
    issues = []
    if claim.get('option') not in counts['options']:
        return ['unknown_option']
    expected = counts['options'][claim['option']]
    if claim.get('count') != expected['count']:
        issues.append('count_mismatch')
    denominator = claim.get('denominator')
    if denominator not in ('all_rows', 'answered_rows'):
        issues.append('denominator_missing_or_unknown')
    elif claim.get('percent') != expected['percent_of_' + denominator]:
        issues.append('percentage_denominator_mismatch')
    if claim.get('proves_population_demand', False):
        issues.append('fictional_fixture_is_not_population_evidence')
    return issues


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--input', required=True, type=Path)
    parser.add_argument('--out', required=True, type=Path)
    args = parser.parse_args()
    raw = args.input.read_bytes()
    result = reference(json.loads(raw))
    result['source_sha256'] = hashlib.sha256(raw).hexdigest()
    controls = [
        ('valid_answered', {'option': 'Clear steps', 'count': 8, 'denominator': 'answered_rows', 'percent': 72.7}, []),
        ('valid_all_rows', {'option': 'Clear steps', 'count': 8, 'denominator': 'all_rows', 'percent': 66.7}, []),
        ('wrong_denominator', {'option': 'Clear steps', 'count': 8, 'denominator': 'answered_rows', 'percent': 66.7}, ['percentage_denominator_mismatch']),
        ('no_denominator', {'option': 'Clear steps', 'count': 8, 'percent': 72.7}, ['denominator_missing_or_unknown']),
        ('inflated_count', {'option': 'Clear steps', 'count': 9, 'denominator': 'answered_rows', 'percent': 72.7}, ['count_mismatch']),
        ('invented_real_demand', {'option': 'Clear steps', 'count': 8, 'denominator': 'answered_rows', 'percent': 72.7, 'proves_population_demand': True}, ['fictional_fixture_is_not_population_evidence']),
    ]
    report = []
    for name, claim, expected in controls:
        actual = claim_issues(claim, result)
        assert actual == expected, (name, actual, expected)
        report.append({'name': name, 'claim': claim, 'issues': actual, 'matches_expected': True})
    args.out.mkdir(parents=True, exist_ok=True)
    (args.out / 'reference-counts.json').write_text(json.dumps(result, indent=2) + '\n', encoding='utf-8')
    (args.out / 'claim-checks.json').write_text(json.dumps({'passed': True, 'controls': report, 'limits': 'Deliberately constructed structured claims; not general natural-language fact checking or model accuracy.'}, indent=2) + '\n', encoding='utf-8')
    print(json.dumps({'rows': result['total_rows'], 'choice_answered': result['choice_answered_rows'], 'options': result['options'], 'claim_checks': len(report), 'passed': True}))


if __name__ == '__main__':
    main()
