"""Read a supplied report CSV; do not infer live provenance from a file alone.
Application state routing only. No real DOI, Crossref request, Grobid extraction or scholarly-match validation.
No network calls or external actions.
"""
import csv, json, hashlib, sys
from pathlib import Path
REQUIRED=['candidate_id', 'document_id', 'raw_reference', 'source_label', 'decision_state', 'review_state']
def blank(value): return value is None or value.strip().lower() in {'', 'null', '(null)'}
def transform(row):
    decision = row['decision_state']
    expected = 'pending_review' if blank(decision) else decision
    if expected not in {'accepted','rejected','pending_review'} or expected != row['review_state']: raise ValueError('Unknown or inconsistent review state')
    if not row['raw_reference'] or not row['source_label']: raise ValueError('Source evidence missing')
    return {'id':row['candidate_id'], 'document':row['document_id'], 'state':expected, 'raw_reference':row['raw_reference'], 'source':row['source_label']}
def route(path):
    path=Path(path); records=[];seen=set()
    with path.open(encoding='utf-8-sig', newline='') as f:
        reader=csv.DictReader(f)
        names=reader.fieldnames or []
        normalized=[s.split('.')[-1].strip('" ') for s in names]
        if len(normalized)!=len(set(normalized)) or not set(REQUIRED).issubset(normalized): raise ValueError('Missing or ambiguous report columns')
        for raw in reader:
            row={new:raw[old] for old,new in zip(names,normalized)}
            key=row['candidate_id']
            if not key or key in seen: raise ValueError('Missing or duplicate record ID')
            seen.add(key); records.append(transform(row))
    if not records: raise ValueError('Empty report cannot verify this fixture')
    return {'input_sha256':hashlib.sha256(path.read_bytes()).hexdigest(), 'source':'Supplied CSV; link console export evidence separately', 'external_actions_sent':False, 'records':records}
if __name__=='__main__':
    if len(sys.argv)!=2: raise SystemExit('Usage: python route-export.py report.csv')
    print(json.dumps(route(sys.argv[1]),indent=2))
