"""Isolated one-row reproduction of configured timeRole loss in Launcher 0.1.35."""
from pathlib import Path
from datetime import datetime
import json, sqlite3, subprocess

LAB = Path(__file__).resolve().parents[1]
P = LAB/'issues/time-role-0.1.35'
E = P/'evidence'/datetime.now().strftime('%Y%m%d-%H%M%S-%f')
E.mkdir(parents=True)
CLI = LAB/'tools/cli/Scripts/foggy-runtime.exe'
NS = 'time-role-repro-035'
MODEL = 'TimeRoleProbeQueryModel'

def save(path, obj):
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(obj, ensure_ascii=False, indent=2), encoding='utf-8')

def call(name, *args):
    cmd = [str(CLI),'--output','json','--base-url','http://127.0.0.1:18067','--namespace',NS,*map(str,args)]
    proc = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', timeout=60)
    (E/(name+'.json')).write_text(proc.stdout,encoding='utf-8')
    if proc.stderr: (E/(name+'.stderr.txt')).write_text(proc.stderr,encoding='utf-8')
    obj = json.loads(proc.stdout)
    with (E/'commands.jsonl').open('a',encoding='utf-8') as f:
        f.write(json.dumps({'label':name,'args':cmd[1:],'exitCode':proc.returncode,'success':obj.get('success')})+'\n')
    assert proc.returncode == 0 and obj.get('success'),(name,obj)
    return obj

call('capabilities','capabilities')
db=P/'time-role-probe.sqlite'
if not db.exists():
    with sqlite3.connect(db) as c:
        c.executescript('''CREATE TABLE TimeRoleProbe (
        RecordId INTEGER PRIMARY KEY, BusinessAt DATETIME NOT NULL,
        LoadedAt DATETIME NOT NULL, CreatedAt DATETIME NOT NULL);
        INSERT INTO TimeRoleProbe VALUES
        (1,'2012-11-29 00:00:00','2012-12-01 00:00:00','2012-11-29 00:00:00');''')
jdbc='jdbc:sqlite:'+str(db).replace('\\','/')
name='time-role-repro-035-sqlite'
ds=call('datasources-before','datasources','list')['data']['datasources']
existing=next((d for d in ds if d['name']==name),None)
if existing: assert existing['jdbcUrl']==jdbc
else: call('datasource-add','datasources','add','--name',name,'--type','sqlite','--jdbc-url',jdbc)
call('datasource-test','datasources','test',name)
call('bind','datasources','bind','--namespace',NS,'--data-source',name)
call('inspect','tables','inspect','--data-source',name,'--table','TimeRoleProbe','--include-indexes')
models=P/'models'
(models/'model').mkdir(parents=True,exist_ok=True)
(models/'query').mkdir(exist_ok=True)
tm="""export const model = {
    name: 'TimeRoleProbeModel', caption: 'Time role probe',
    tableName: 'TimeRoleProbe', idColumn: 'RecordId',
    properties: [
        {column: 'RecordId', name: 'recordId', type: 'INTEGER'},
        {column: 'BusinessAt', name: 'businessAt', type: 'DATETIME',
         timeRole: 'business_date', recommendedUse: 'business_axis_control'},
        {column: 'LoadedAt', name: 'loadedAt', type: 'DATETIME',
         timeRole: 'system_time', recommendedUse: 'technical_ingestion_only'},
        {column: 'CreatedAt', name: 'createdAt', type: 'DATETIME',
         timeRole: 'business_date', recommendedUse: 'explicit_business_axis'}
    ],
    dimensions: [{
        name: 'loadedTime', caption: 'Technical ingestion',
        foreignKey: 'LoadedAt', primaryKey: 'LoadedAt', captionColumn: 'LoadedAt',
        type: 'DATETIME', timeRole: 'system_time',
        recommendedUse: 'technical_ingestion_dimension_only'
    }],
    measures: []
};
"""
qm="""const probe = loadTableModel('TimeRoleProbeModel');
export const queryModel = {
    name: 'TimeRoleProbeQueryModel', caption: 'Time role probe',
    loader: 'v2', model: probe,
    columnGroups: [{caption: 'Times', items: [
        {ref: probe.recordId}, {ref: probe.businessAt},
        {ref: probe.loadedAt}, {ref: probe.createdAt}, {ref: probe.loadedTime}
    ]}], accesses: []
};
"""
(models/'model/TimeRoleProbeModel.tm').write_text(tm,encoding='utf-8')
(models/'query/TimeRoleProbeQueryModel.qm').write_text(qm,encoding='utf-8')
call('models-validate','models','validate','--models-dir',models,'--include-stack-trace')
call('bundle','bundles','add','--name','time-role-repro-035','--path',models,'--replace')
call('refresh','models','refresh')
obj=call('describe-json','models','describe',MODEL)
md=call('describe-markdown','models','describe',MODEL,'--format','markdown')
(E/'metadata.md').write_text(md['data']['content'],encoding='utf-8')
fields=obj['data']['data']['fields']
actual={key:{k:v for k,v in fields[key].items() if k in ['fieldName','type','timeRole','recommendedUse']}
        for key in ['businessAt','loadedAt','createdAt','loadedTime$id']}
rolelines=[line for line in md['data']['content'].splitlines() if line.startswith(('| businessAt |','| loadedAt |','| createdAt |','| loadedTime$id |'))]
summary={'namespace':NS,'runtime':'http://127.0.0.1:18067','expected':{
    'businessAt':{'timeRole':'business_date','recommendedUse':'business_axis_control'},
    'loadedAt':{'timeRole':'system_time','recommendedUse':'technical_ingestion_only'},
    'createdAt':{'timeRole':'business_date','recommendedUse':'explicit_business_axis'},
    'loadedTime$id':{'timeRole':'system_time','recommendedUse':'technical_ingestion_dimension_only'}},
    'actualJson':actual,'actualMarkdownLines':rolelines,'modelValidationSucceeded':True,
    'sourceCodeNotModified':True,'evidenceDirectory':str(E)}
assert actual['loadedAt']['timeRole']=='business_date'
assert actual['createdAt']['timeRole']=='system_time'
assert all('recommendedUse' not in actual[k] for k in ['businessAt','loadedAt','createdAt'])
assert 'timeRole' not in actual['loadedTime$id']
assert any('loadedTime$id' in line and 'system_time' in line and 'technical_ingestion_dimension_only' in line for line in rolelines)
save(E/'reproduction.json',summary)
save(P/'latest-run.json',{'evidenceDirectory':str(E)})
print(json.dumps(summary,ensure_ascii=True,indent=2))
