"""Offline, deterministic teaching experiments. No model calls are made."""
import csv, json, math
from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
HERE = Path(__file__).resolve().parent

def inspect_csv(path):
    with path.open(encoding='utf-8-sig', newline='') as f:
        reader = csv.DictReader(f)
        required = {'name', 'path', 'kind'}
        missing = required - set(reader.fieldnames or [])
        if missing:
            raise ValueError('missing columns: ' + ','.join(sorted(missing)))
        rows = list(reader)
    problems, seen = [], set()
    for line, row in enumerate(rows, 2):
        for field in sorted(required):
            if not (row.get(field) or '').strip():
                problems.append({'line':line,'rule':'empty','field':field})
        name = (row.get('name') or '').strip()
        if name:
            if name in seen: problems.append({'line':line,'rule':'duplicate','field':'name'})
            seen.add(name)
            prefix = {'texture':'T_', 'mesh':'SM_'}.get(row.get('kind',''))
            if prefix and not name.startswith(prefix):
                problems.append({'line':line,'rule':'prefix','field':'name'})
    return {'rows':len(rows),'issues':problems}

def main():
    out = ROOT/'检查记录'
    out.mkdir(exist_ok=True)
    current = inspect_csv(HERE/'assets.csv')
    # The teaching policy accepts uppercase PNG; the old comparison is case-sensitive.
    old = [Path('资产/T_Rock.PNG').suffix == '.png']
    fixed = [Path('资产/T_Rock.PNG').suffix.lower() == '.png']
    assert old == [False] and fixed == [True]
    expected = [(3,'prefix','name'),(4,'duplicate','name'),(5,'empty','name'),(5,'empty','path')]
    assert [(x['line'],x['rule'],x['field']) for x in current['issues']] == expected
    try: inspect_csv(HERE/'missing_columns.csv')
    except ValueError as e: schema_error = str(e)
    else: raise AssertionError('missing columns must fail')
    missing_file = HERE/'__missing_fixture__.csv'
    assert not missing_file.exists(), 'the missing-file fixture must not exist'
    try: inspect_csv(missing_file)
    except FileNotFoundError as e: file_error = type(e).__name__
    else: raise AssertionError('the missing file must fail')
    logits = [3.0, 2.0, 1.0]
    dist = {}
    for temp in [.5,1.0,2.0]:
        exp=[math.exp((x-max(logits))/temp) for x in logits]
        dist[str(temp)]=[round(x/sum(exp),6) for x in exp]
    log=[{'step':1,'actor':'scripted_fixture','decision':'inspect missing file',
          'tool':'inspect_csv','path':str(missing_file),'result':file_error,'executed':True},
         {'step':2,'actor':'scripted_fixture','decision':'use explicit sample path',
          'tool':'inspect_csv','result':current},
         {'step':3,'actor':'validator','decision':'accept report',
          'evidence':'four issues match expected line/rule pairs'}]
    # Contrast cases are complete inputs, not fabricated model responses.
    source=Path(__file__).read_text(encoding='utf-8').split('def inspect_csv(path):',1)[1].split('\ndef main():',1)[0]
    function='def inspect_csv(path):'+source
    sample=(HERE/'assets.csv').read_text(encoding='utf-8-sig')
    prompts=[{'case':'question_only','input':'解释资产命名检查脚本。','model_run':False},
             {'case':'with_code','input':'解释 inspect_csv 的输入、规则和输出。\n代码：\n'+function,'model_run':False},
             {'case':'with_code_and_data','input':'解释 inspect_csv，使用以下样本逐行指出问题；不重命名资产。\n代码：\n'+function+'\nCSV：\n'+sample,'model_run':False}]
    values=[10,12,None,14,16]
    valid=[x for x in values if x is not None]
    assert sum(valid)/len(valid)==13 and sum(valid)/len(values)==10.4
    result={'date':'2026-10-10','experiment':'deterministic teaching fixture',
            'frame_time_teaching_data':{'values_ms':values,'valid_count':len(valid),'missing_count':1,
                                       'valid_mean_ms':13,'incorrect_zero_fill_mean_ms':10.4},
            'model_calls':0,'csv':current,'schema_error':schema_error,
            'regression':{'before':old,'after':fixed},'logits':logits,'temperature':dist,
            'scripted_tool_trace':log,'context_inputs':prompts}
    (out/'学习实验结果.json').write_text(json.dumps(result,ensure_ascii=False,indent=2),encoding='utf-8')
    print(json.dumps({'date':result['date'],'model_calls':0,'rows':current['rows'],
                      'issues':len(current['issues']),'missing_file_error':file_error,
                      'frame_mean_ms':13,'context_cases':len(prompts),'passed':True},ensure_ascii=False))

if __name__ == '__main__': main()
