"""Generate validated simulation-only entry ceilings from actual marked equity."""
from data_paths import default_db_path
import argparse
import json
import os
import tempfile
from pathlib import Path
from decimal import Decimal
from ledger_reporting import read_snapshot, Rejected, number, instant, timestamp

CRYPTO='Phase1-Crypto-Sandbox'
FUTURES='Phase1-Futures-Sandbox'

def atomic_json(path,payload):
    from infinbot_common import atomic_json as write_json,private_read,strict_json
    target=Path(path).absolute()
    if target.suffix!='.json' or str(target)==payload['database_path']:raise Rejected('Policy output must be a separate JSON file')
    if target.exists():
        old=strict_json(private_read(target))
        if old.get('status')!='SIMULATION_POLICY_SNAPSHOT':raise Rejected('Existing non-policy output preserved')
    write_json(target,payload,replace=target.exists())

class QuantRiskRebalanceEngine:
    def __init__(self,db_filepath=str(default_db_path('foresixa_day1_v2_fixture.db')),config_out='active_risk_params.json'):
        self.db_filepath=db_filepath;self.config_out=config_out
    def execute_dynamic_rebalance(self):
        s=read_snapshot(self.db_filepath);a=s['account'];eq=number(s['equity'],True)
        enabled=False
        half=Decimal(0)
        payload={'schema_version':1,'status':'SIMULATION_POLICY_SNAPSHOT','rebalanced_at':s['observed_at'],
            'database_path':s['database_path'],'account_started_at':a['started_at'],
            'data_origin':s['data_origin'],'expires_after_seconds':604800,
            'budget_semantics':'PER_ENTRY_PLANNED_LOSS_CEILING_NOT_WEEKLY_CUMULATIVE_LOSS',
            'portfolio_metrics':{'marked_equity':str(eq),'cash':s['cash'],'open_market_value':s['open_market_value'],'enforced_global_rate':'0.01'},
            'worker_allocations':{
                CRYPTO:{'asset_class':'CRYPTO','enabled':enabled,'per_trade_risk_rate':'0.005','per_trade_risk_cap_dollars':str(half),'weekly_max_risk_dollars':str(half)},
                FUTURES:{'asset_class':'FUTURES','enabled':False,'per_trade_risk_rate':'0.005','per_trade_risk_cap_dollars':'0','weekly_max_risk_dollars':'0','reserved_diagnostic_budget':str(half),'reason':'Futures execution disabled; allocation is not transferred to crypto'}},
            'circuit_breakers':{'daily_baseline_equity':a['session_equity'],'daily_drawdown_limit_dollars':str(number(a['session_equity'])*Decimal('.03')),'halted':bool(a['halted']),'maximum_leverage_ratio':'1:1'},
            'live_execution_enabled':False,'trial_days_credited':0}
        atomic_json(self.config_out,payload);return payload
    def close(self):pass

def load_risk_limits(filepath,db_filepath,tag):
    try:
        payload=json.loads(Path(filepath).read_text())
        if payload['schema_version']!=1 or payload['status']!='SIMULATION_POLICY_SNAPSHOT':raise Rejected('Unsupported risk snapshot')
        from datetime import datetime,timezone
        age=(datetime.now(timezone.utc)-instant(payload['rebalanced_at'])).total_seconds()
        if not -5<=age<=604800 or payload['expires_after_seconds']!=604800:raise Rejected('Expired or future risk snapshot')
        if payload['database_path']!=str(Path(db_filepath).resolve()):raise Rejected('Risk snapshot belongs to a different database')
        s=read_snapshot(db_filepath)
        if payload['account_started_at']!=s['account']['started_at']:raise Rejected('Risk snapshot belongs to a different account')
        raise Rejected('InFinBot repair release enforces a persistent entry freeze')
        worker=payload['worker_allocations'][tag]
        if tag!=CRYPTO or worker['asset_class']!='CRYPTO' or worker['enabled'] is not True:raise Rejected('Worker execution disabled or not configured')
        rate=number(worker['per_trade_risk_rate'],True)
        if rate>Decimal('.005'):raise Rejected('Worker risk rate exceeds configured 50% share of 1% ceiling')
        return {'per_trade_rate':str(rate),'snapshot_cap':str(number(worker['per_trade_risk_cap_dollars'],True))}
    except (OSError,ValueError,KeyError,TypeError) as exc:
        if isinstance(exc,Rejected):raise
        raise Rejected('Risk snapshot missing or malformed; entries fail closed') from exc

def main():
    parser=argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--db-path',required=True);parser.add_argument('--config-out',default='active_risk_params.json');args=parser.parse_args()
    try:
        print(json.dumps(QuantRiskRebalanceEngine(args.db_path,args.config_out).execute_dynamic_rebalance(),indent=2));return 0
    except Rejected as exc:
        print(json.dumps({'status':'REBALANCE_BLOCKED','reason':str(exc)}));return 1
if __name__=='__main__':raise SystemExit(main())
