"""Bounded reject-on-risk CSV policy with harmless fixtures. No spreadsheet executed."""
import csv,io,json,re,unicodedata
from pathlib import Path
P=Path(__file__).resolve().parent

def safe_text(value):
    if any(unicodedata.category(c) in {'Cc','Cf'} for c in value):
        raise ValueError('control or format character')
    probe=unicodedata.normalize('NFKC',value).lstrip()
    if probe.startswith(('=','+','-','@')):
        raise ValueError('formula-like leading character')
    return value

def number(value):
    if not re.fullmatch(r'-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?',value):
        raise ValueError('invalid bounded decimal grammar')
    return value
cases=[('plain','text','Report ready',True),('comma','text','Paris, France',True),('quote','text','A "quoted" label',True),('equals','text','=1+1',False),('plus','text','+1+1',False),('minus_text','text','-1+1',False),('at','text','@SUM(1,1)',False),('tab','text','\t=1+1',False),('fullwidth','text','＝1+1',False),('newline','text','\n=1+1',False),('negative_number','number','-12.50',True),('zero','number','0',True)]
results=[];accepted=[]
for label,kind,value,expected in cases:
    try:out=(safe_text if kind=='text' else number)(value);ok=True;reason='accepted unchanged'
    except ValueError as e:ok=False;reason=str(e)
    assert ok==expected
    results.append({'case':label,'kind':kind,'input':value,'accepted':ok,'reason':reason})
    if ok:accepted.append([label,out])
s=io.StringIO(newline='');w=csv.writer(s);w.writerow(['case','value']);w.writerows(accepted)
parsed=list(csv.reader(io.StringIO(s.getvalue(),newline='')))
assert parsed==[['case','value']]+accepted
for invalid in ['NaN','Infinity','1e3','=1+1','1,000']:
    try:number(invalid)
    except ValueError:pass
    else:raise AssertionError(invalid)
(P/'accepted-export.csv').write_text(s.getvalue(),newline='')
(P/'results.json').write_text(json.dumps({'cases':results,'accepted':len(accepted),'rejected':len(results)-len(accepted),'roundTrip':'Python csv writer/reader preserves all accepted values','numericRejections':5,'scope':'Bounded input policy and CSV parser round trip only. No Excel, Sheets, LibreOffice, save/reopen or formula execution tested.'},indent=2)+'\n')
print('12 cases: 5 accepted, 7 rejected; accepted writer/reader round trip passed')
