"""Read the CURRENT office server SQLite database without changing it.
Copy this and Export_Current_Server.cmd beside the office app's server.py,
or run: python export_current_server.py --app-folder C:\\ManhourCentral
"""
import argparse,datetime,hashlib,json,sqlite3,sys
from pathlib import Path

def export(app_folder,output=None):
    app=Path(app_folder).resolve()
    settings_file=app/'server-settings.json'
    if not settings_file.exists():raise ValueError('Choose the running central app folder containing server-settings.json. Do not select the downloaded ZIP or seed data.')
    settings=json.loads(settings_file.read_text(encoding='utf-8-sig'))
    data_dir=Path(settings.get('data_dir','data'))
    dbpath=(app/data_dir/'manhour.sqlite3').resolve()
    if not dbpath.is_file():raise ValueError('Current central database not found at '+str(dbpath))
    with sqlite3.connect(dbpath.as_uri()+'?mode=ro',uri=True,timeout=30) as db:
        db.row_factory=sqlite3.Row;db.execute('BEGIN')
        meta={r['key']:json.loads(r['value']) for r in db.execute('SELECT key,value FROM meta')}
        cfg=meta['config']
        if not cfg.get('nov4Upgrade') or not cfg.get('nov9ExpectedTeams'):
            raise ValueError('Update the current office app to the November release, start it once with its existing database, then export again.')
        rows=[];deleted=[]
        for r in db.execute('SELECT * FROM records ORDER BY team,id'):
            value={'id':r['id'],'kind':r['kind'],'team':r['team'],'payload':json.loads(r['payload']),'revision':r['revision'],'updatedAt':r['updated_at'],'updatedBy':r['updated_by']}
            (deleted if r['deleted'] else rows).append(value)
        audit=[dict(r) for r in db.execute('SELECT at,who,action,before_value,after_value FROM audit ORDER BY id')]
        result={'format':'paradigm-manhour-central-v1','savedAt':datetime.datetime.now(datetime.timezone.utc).isoformat(),'config':cfg,'configRevision':meta.get('configRevision',1),'dataRevision':meta.get('dataRevision',1),'databaseEpoch':meta.get('databaseEpoch'),'records':rows,'transferDeletedRecords':deleted,'transferAudit':audit}
        db.commit()
    if output is None:output=app/('Manhour_Server_Transfer_'+datetime.datetime.now().strftime('%Y%m%d_%H%M%S')+'.json')
    target=Path(output).resolve()
    if target.exists():raise ValueError('Output file already exists; choose a new filename.')
    raw=json.dumps(result,ensure_ascii=False,allow_nan=False,indent=2).encode('utf-8')
    with target.open('xb') as f:f.write(raw)
    print('Exported CURRENT central-server data:',target)
    print('Project rows:',sum(r['kind']=='project' for r in rows),'Employee rows:',sum(r['kind']=='employee' for r in rows),'Audit entries:',len(audit),'Archived deleted rows:',len(deleted))
    print('SHA256:',hashlib.sha256(raw).hexdigest())
    print('No source records or settings were changed. Access codes are not exported.')
    return result
if __name__=='__main__':
    p=argparse.ArgumentParser();p.add_argument('--app-folder',default=str(Path(__file__).resolve().parent));p.add_argument('--output');args=p.parse_args()
    try:export(args.app_folder,args.output)
    except Exception as e:print('Export failed:',e,file=sys.stderr);sys.exit(1)
