"""Strict extraction for the exact binary SPSS logistic-model structure used here."""
if not __debug__:
    raise RuntimeError("Validation requires assertions; run Python without -O or PYTHONOPTIMIZE.")
import csv,io,math,xml.etree.ElementTree as ET
NS={'p':'http://www.dmg.org/PMML-4_3'}
def extract(path):
    root=ET.parse(path).getroot()
    assert root.tag=='{'+NS['p']+'}PMML' and root.attrib['version']=='4.3'
    # Accept only elements in the retained SPSS structure, including metadata.
    # A suffix check misses model types such as NeuralNetwork and Scorecard.
    supported={'PMML','Header','Application','Extension','DataDictionary','DataField','Value',
               'GeneralRegressionModel','MiningSchema','MiningField','ParameterList','Parameter',
               'CovariateList','Predictor','PPMatrix','PPCell','PCovMatrix','PCovCell',
               'ParamMatrix','PCell','FactorList','LocalTransformations'}
    assert all(e.tag in {'{'+NS['p']+'}'+name for name in supported} for e in root.iter()), 'Unsupported PMML element'
    models=root.findall('p:GeneralRegressionModel',NS)
    assert len(models)==1 and len(root.findall('.//p:GeneralRegressionModel',NS))==1
    assert not any(e.tag.endswith('Model') and e is not models[0] for e in root.iter())
    model=models[0]
    assert set(model.attrib)<={'modelType','functionName','targetVariableName','targetReferenceCategory','algorithmName','modelName'}, 'Unsupported model attributes'
    for key,value in {'modelType':'multinomialLogistic','functionName':'classification','targetVariableName':'exceed','targetReferenceCategory':'1'}.items():
        assert model.attrib.get(key)==value,('Unexpected model structure',key)
    fields=root.findall('p:DataDictionary/p:DataField',NS)
    assert len(fields)==3 and {e.attrib['name'] for e in fields}=={'exceed','x_range','x_body'}
    for field in fields:
        assert set(field.attrib)<={'name','displayName','optype','dataType'}
        assert field.attrib['dataType']=='double'
        assert field.attrib['optype']==('categorical' if field.attrib['name']=='exceed' else 'continuous')
        assert all(e.tag in {'{'+NS['p']+'}Extension','{'+NS['p']+'}Value'} for e in field)
        if field.attrib['name']!='exceed':
            assert not field.findall('p:Value',NS), 'Unsupported predictor value treatment'
    target=next(e for e in fields if e.attrib['name']=='exceed')
    assert target.attrib['optype']=='categorical'
    values=target.findall('p:Value',NS)
    assert len(values)==2 and {e.attrib['value'] for e in values}=={'0','1'}
    assert all(set(e.attrib)<={'value','displayValue','property'} and e.attrib.get('property','valid')=='valid' for e in values)
    mining=model.findall('p:MiningSchema/p:MiningField',NS)
    assert len(mining)==3 and {(e.attrib['name'],e.attrib['usageType']) for e in mining}=={('exceed','predicted'),('x_range','active'),('x_body','active')}
    assert all(set(e.attrib)<={'name','usageType','missingValueTreatment'} and e.attrib.get('missingValueTreatment','asIs')=='asIs' for e in mining), 'Unsupported mining-field preprocessing'
    covariates=model.findall('p:CovariateList/p:Predictor',NS)
    assert len(covariates)==2 and {e.attrib['name'] for e in covariates}=={'x_range','x_body'}
    assert all(set(e.attrib)=={'name'} and len(e)==0 for e in covariates), 'Unsupported predictor transformation'
    assert not model.findall('p:FactorList/*',NS) and not model.findall('p:LocalTransformations/*',NS)
    parameters=model.findall('p:ParameterList/p:Parameter',NS)
    assert len(parameters)==3 and len({e.attrib['name'] for e in parameters})==3
    assert all(set(e.attrib)<={'name','label'} for e in parameters), 'Unsupported parameter transformation'
    constants=[e.attrib['name'] for e in parameters if e.attrib.get('label')=='Constant']
    assert len(constants)==1
    mapping={constants[0]:'Constant'}
    cells=model.findall('p:PPMatrix/p:PPCell',NS)
    assert len(cells)==2
    for cell in cells:
        assert set(cell.attrib)=={'parameterName','predictorName','value'}
        key=cell.attrib['parameterName'];name=cell.attrib['predictorName']
        assert key not in mapping and name in {'x_range','x_body'} and float(cell.attrib['value'])==1
        mapping[key]=name
    assert set(mapping)=={e.attrib['name'] for e in parameters} and set(mapping.values())=={'Constant','x_range','x_body'}
    coeff={};cells=model.findall('p:ParamMatrix/p:PCell',NS)
    assert len(cells)==3
    for cell in cells:
        assert set(cell.attrib)<={'targetCategory','parameterName','beta','df'}
        assert cell.attrib['targetCategory']=='1','Unexpected modeled event category'
        name=mapping[cell.attrib['parameterName']]
        assert name not in coeff,'Duplicate model coefficient'
        coeff[name]=float(cell.attrib['beta'])
    assert all(math.isfinite(value) for value in coeff.values())
    return coeff

def coefficient_csv(coeff):
    f=io.StringIO(newline='');w=csv.writer(f);w.writerow(['term','coefficient'])
    for name in ('Constant','x_range','x_body'):w.writerow([name,format(coeff[name],'.17g')])
    return f.getvalue()

def publish_coefficients(coeff,target):
    temp=target.with_suffix('.tmp');
    with temp.open('w',newline='') as f:f.write(coefficient_csv(coeff))
    temp.replace(target)
