"""Public sample/fixture parsing only. Never seeds ledgers or establishes live feeds."""
import argparse,csv,gzip,io,json,re
from pathlib import Path
from datetime import date,datetime
from decimal import Decimal
from infinbot_common import strict_json,number,instant,Rejected
from datamine_adapter import FIELDS,MAX_FILE,MAX_EXPANDED,exact_uint

def alpaca_bars(raw,asset_class):
    if asset_class not in ('STOCKS','OPTIONS'):raise Rejected('Explicit stocks/options profile required')
    payload=strict_json(raw)
    if not isinstance(payload,dict) or set(payload)!={'bars','next_page_token'} or not isinstance(payload['bars'],dict) or not payload['bars']:
        raise Rejected('Complete Alpaca bars page required')
    if payload['next_page_token'] is not None and not isinstance(payload['next_page_token'],str):raise Rejected('Invalid pagination token')
    count=0
    for symbol,bars in payload['bars'].items():
        pattern=r'[A-Z][A-Z0-9.]{0,9}' if asset_class=='STOCKS' else r'[A-Z]{1,6}(\d{6})[CP]\d{8}'
        match=re.fullmatch(pattern,symbol)
        if not match or not isinstance(bars,list) or not bars:raise Rejected('Explicit matching instrument and nonempty bars required')
        if asset_class=='OPTIONS':datetime.strptime(match.group(1),'%y%m%d')
        prior=None
        for bar in bars:
            if not isinstance(bar,dict) or set(bar)!={'t','o','h','l','c','v','n','vw'}:raise Rejected('Complete bar fields required')
            at=instant(bar['t'])
            if prior is not None and at<=prior:raise Rejected('Duplicate/decreasing bar timestamp')
            prior=at;values={k:number(bar[k]) for k in ('o','h','l','c','v','vw')}
            if min(values.values())<0 or not values['l']<=min(values['o'],values['c'])<=max(values['o'],values['c'])<=values['h']:
                raise Rejected('Invalid OHLC/volume values')
            if type(bar['n']) is not int or bar['n']<0:raise Rejected('Nonnegative recorded trade count required')
            count+=1
    return {'asset_class':asset_class,'rows_validated':count,'symbols':sorted(payload['bars']),
            'prices_parsed_with_decimal':True,'pagination_complete':payload['next_page_token'] is None,
            'input_provenance':'PROVIDER_PUBLISHED_TEST_FIXTURE','live_feed_verified':False,'ledger_modified':False}

def cme_options(raw,product):
    if len(raw)>MAX_FILE or not re.fullmatch(r'[A-Z0-9]{1,12}',product):raise Rejected('Bounded explicit product required')
    source=gzip.GzipFile(fileobj=io.BytesIO(raw)) if raw.startswith(b'\x1f\x8b') else io.BytesIO(raw)
    rows=trades=volumes=strategies=nonexecutions=negative_strategy=0;sequences={};earliest=None;latest=None
    with source,io.TextIOWrapper(source,encoding='utf-8-sig',newline='') as text:
        total=0
        def lines():
            nonlocal total
            for line in text:
                total+=len(line.encode())
                if total>MAX_EXPANDED or len(line)>8192:raise Rejected('Expanded source exceeds bounds')
                yield line
        reader=csv.DictReader(lines())
        if tuple(reader.fieldnames or ())!=FIELDS:raise Rejected('Exact v2 options header required')
        for r in reader:
            if set(r)!=set(FIELDS) or any(not isinstance(v,str) or len(v)>256 for v in r.values()):raise Rejected('Bounded complete options row required')
            if r['Ticker_Symbol']!=product or r['Future_Option_Index_Indicator']!='OPT' or r['Exchange_Code']!='XCME':raise Rejected('Explicit CME options product mismatch')
            t=r['Transaction_Time']
            if not re.fullmatch(r'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{9}Z',t):raise Rejected('UTC nanosecond timestamp required')
            instant(t);day=date.fromisoformat(r['Transaction_Date'])
            if t[:10]!=day.isoformat():raise Rejected('Date/timestamp mismatch')
            security=exact_uint(r['Security_ID'],True);scope=(day,security)
            kind=r['Market_Data_Report_Type']
            if r['Sequence_Number']:
                seq=exact_uint(r['Sequence_Number'],True)
                if seq<=sequences.get(scope,0):raise Rejected('Duplicate/decreasing security sequence')
                sequences[scope]=seq
            elif kind!='VOL':raise Rejected('Trade sequence required')
            if not re.fullmatch(r'\d{6}(?:w[1-5])?',r['Delivery_Date']):raise Rejected('Explicit monthly/weekly delivery label required')
            datetime.strptime(r['Delivery_Date'][:6],'%Y%m')
            if r['User_Defined'] not in ('H','U'):raise Rejected('Declared instrument origin required')
            strategy=r['Instrument_Symbol'].startswith('UD:')
            if strategy:
                if r['User_Defined']!='U':raise Rejected('Explicit user-defined strategy reference required')
                if r['Put_Call_Indicator'] not in ('','C','P'):raise Rejected('Invalid option side')
                if r['Strike_Price']:number(r['Strike_Price'])
                strategies+=1
            else:
                if r['Put_Call_Indicator'] not in ('C','P'):raise Rejected('Declared option side required')
                number(r['Strike_Price'],positive=True)
                if not re.fullmatch(re.escape(product)+r'[FGHJKMNQUVXZ]\d{1,4} [CP]\d+(?:\.\d+)?',r['Instrument_Symbol']):raise Rejected('Explicit outright option symbol required')
            if r['Trade_Aggressor'] not in ('','B','A') or r['Close_Open_Type'] not in ('','O'):raise Rejected('Invalid enumeration')
            if r['Vol_Quantity']:exact_uint(r['Vol_Quantity'])
            if kind=='TRD':
                price=number(r['Trade_Price_Decimal'])
                if price<0:
                    if not strategy:raise Rejected('Negative outright option price')
                    negative_strategy+=1
                if r['Trade_Quantity'] and exact_uint(r['Trade_Quantity'])>0:trades+=1
                else:nonexecutions+=1
            elif kind=='VOL':
                if r['Trade_Price_Decimal'] or r['Trade_Price_Formatted'] or r['Trade_Quantity']:raise Rejected('VOL is not an execution')
                volumes+=1
            else:raise Rejected('Unsupported report type')
            rows+=1;earliest=t if earliest is None or t<earliest else earliest;latest=t if latest is None or t>latest else latest
    if not rows:raise Rejected('Empty sample unavailable')
    return {'rows_validated':rows,'trade_records':trades,'volume_records':volumes,'strategy_rows':strategies,
            'negative_strategy_prices':negative_strategy,'non_execution_price_records':nonexecutions,
            'earliest_source_timestamp':earliest,'latest_source_timestamp':latest,
            'prices_parsed_with_decimal':True,'input_provenance':'OFFICIAL_PUBLIC_CME_HISTORICAL_SAMPLE',
            'strategy_leg_allocation_verified':False,'display_factor_applied':False,'live_feed_verified':False,'ledger_modified':False}

if __name__=='__main__':
    p=argparse.ArgumentParser(description=__doc__);p.add_argument('--file',required=True)
    p.add_argument('--profile',required=True,choices=('stocks','options','cme-options'));p.add_argument('--product');a=p.parse_args()
    try:
        path=Path(a.file)
        if path.is_symlink() or not path.is_file() or path.stat().st_size>MAX_FILE:raise Rejected('Bounded regular sample required')
        raw=path.read_bytes();result=cme_options(raw,a.product) if a.profile=='cme-options' else alpaca_bars(raw,a.profile.upper())
        print(json.dumps(result,indent=2))
    except Exception:print(json.dumps({'status':'SAMPLE_VALIDATION_BLOCKED','ledger_modified':False}));raise SystemExit(1)
