"""Funded same-target settlement ledgers on the existing synthetic CSV.

Initial1000 units, target2x, integer cents, no deposits/fees, equality wins.
Fixed50, fixed10, or0.5% current balance floored to cents with minimum0.10.
Stop before an unfunded wager. These are single synthetic paths, not ruin rates.
Usage: python ruin_ledgers.py [dataset.csv] [--ledger output.csv]
"""
import argparse
import csv
from decimal import Decimal
from fractions import Fraction
import hashlib
import json
import logging
from pathlib import Path


def replay(path):
    expected='0f3341c5dc53667e4e7b36c80998461ad0d215ce8608dded2d72c27d9bf7ab10'
    if hashlib.sha256(path.read_bytes()).hexdigest()!=expected:
        raise ValueError('File differs from the documented synthetic corpus')
    with path.open(encoding='utf-8',newline='') as stream:
        rounds=list(csv.DictReader(stream))
    summaries,ledger=[],[]
    for name,fixed in [('fixed50',5000),('fixed10',1000),('current0.5percent',None)]:
        balance=peak=100000
        turnover=gross=wins=executed=0
        worst=Fraction(0)
        unfunded=None
        for row in rounds:
            stake=fixed if fixed is not None else max(10,balance*5//1000)
            if balance<stake:
                unfunded=int(row['round_id'])
                break
            before=balance
            won=Decimal(row['multiplier'])>=2
            paid=2*stake if won else 0
            balance+=paid-stake
            turnover+=stake;gross+=paid;wins+=won;executed+=1
            peak=max(peak,balance)
            worst=max(worst,Fraction(peak-balance,peak))
            ledger.append(dict(model=name,roundId=int(row['round_id']),
                balanceBeforeCents=before,stakeCents=stake,won=won,
                grossCents=paid,balanceAfterCents=balance,peakCents=peak))
        assert balance==100000+gross-turnover
        summaries.append(dict(model=name,executedRounds=executed,wins=wins,
            firstUnfundedRound=unfunded,turnoverCents=turnover,grossCents=gross,
            finalBalanceCents=balance,netCents=gross-turnover,
            realisedRtp=gross/turnover if turnover else None,
            maxDrawdown=float(worst),maxDrawdownExact=str(worst)))
    return dict(scope='One synthetic path, not a live experiment or population ruin estimate',
                datasetSha256=expected,startingBalanceCents=100000,results=summaries),ledger


if __name__=='__main__':
    parser=argparse.ArgumentParser(description=__doc__)
    parser.add_argument('dataset',nargs='?',type=Path,default=Path(__file__).with_name('crashmath_10000_rounds_dataset.csv'))
    parser.add_argument('--ledger',type=Path)
    args=parser.parse_args();summary,ledger=replay(args.dataset)
    if args.ledger:
        with args.ledger.open('w',encoding='utf-8',newline='') as stream:
            writer=csv.DictWriter(stream,fieldnames=ledger[0].keys());writer.writeheader();writer.writerows(ledger)
    logging.basicConfig(level=logging.INFO,format='%(message)s')
    logging.info(json.dumps(summary,indent=2))
