"""Small scalar-array mapping, with CSV-to-JSON semantic reconstruction.
python primitive-array-to-csv.py primitive-array.json new-output.csv
"""
import csv,json,sys
from pathlib import Path

def reject_constant(value):raise ValueError('non-JSON constant: '+value)
def kind(value):
    if value is None:return 'null'
    if isinstance(value,bool):return 'boolean'
    if isinstance(value,(int,float)):return 'number'
    if isinstance(value,str):return 'string'
    raise ValueError('only scalar array elements supported')

def export(source,target):
    values=json.loads(Path(source).read_text(encoding='utf-8'),parse_constant=reject_constant)
    if not isinstance(values,list):raise ValueError('top-level array required')
    rows=[[i,kind(value),json.dumps(value,ensure_ascii=False,allow_nan=False)]
          for i,value in enumerate(values)]
    with Path(target).open('x',encoding='utf-8',newline='') as file:
        writer=csv.writer(file);writer.writerow(['index','json_type','value_json']);writer.writerows(rows)
    with Path(target).open(encoding='utf-8',newline='') as file:parsed=list(csv.DictReader(file))
    restored=[]
    for expected,row in enumerate(parsed):
        if int(row['index'])!=expected:raise ValueError('index order changed')
        value=json.loads(row['value_json'],parse_constant=reject_constant)
        if kind(value)!=row['json_type']:raise ValueError('type mismatch')
        restored.append(value)
    if len(restored)!=len(values) or any(type(a)!=type(b) or a!=b for a,b in zip(values,restored)):
        raise ValueError('semantic reconstruction mismatch')
    return {'records':len(parsed),'columns':3,'rows':parsed,'restored':restored,'type_and_value_match':True}

if __name__=='__main__':print(json.dumps(export(*sys.argv[1:3]),ensure_ascii=False))
