#!/usr/bin/env python3
"""Beispiel-Client: schickt signierte 128-Byte-Rahmen an den TerraSol-Dienst.

    python3 beispiel_client.py HOST[:PORT] [ANZAHL]

Rahmen: [0..32] Pubkey | [32..96] ed25519-Signatur über die 32 Nutzbytes |
[96..128] nonce u64 | markt u32 | tick u32 | menge u64 | flags u32 | füll u32
flags: Bit 0 Kauf, Bit 1 Stornieren (menge = Order-Nummer), Bit 2 IOC.
Braucht nur `solders` (pip install solders)."""
import socket, struct, sys, time
from solders.keypair import Keypair

def rahmen(kp: Keypair, nonce: int, tick: int, menge: int, flags: int) -> bytes:
    nutz = struct.pack("<QIIQII", nonce, 0, tick, menge, flags, 0)
    assert len(nutz) == 32
    sig = bytes(kp.sign_message(nutz))
    return bytes(kp.pubkey()) + sig + nutz

def main() -> int:
    ziel = sys.argv[1] if len(sys.argv) > 1 else "127.0.0.1:7420"
    anzahl = int(sys.argv[2]) if len(sys.argv) > 2 else 1000
    host, _, port = ziel.partition(":")
    kp = Keypair()
    mitte = 32768
    with socket.create_connection((host, int(port or 7420)), timeout=10) as s:
        start = time.time()
        puffer = bytearray()
        for i in range(anzahl):
            kauf = i % 2 == 0
            tick = mitte - 5 - (i % 50) if kauf else mitte + 5 + (i % 50)
            puffer += rahmen(kp, i + 1, tick, 1 + i % 20, 1 if kauf else 0)
            if len(puffer) >= 128 * 256:
                s.sendall(puffer); puffer.clear()
        # eine absichtlich kaputte Signatur - der Dienst muss sie ablehnen
        kaputt = bytearray(rahmen(kp, anzahl + 1, mitte, 1, 1)); kaputt[40] ^= 0xFF
        puffer += bytes(kaputt)
        s.sendall(puffer)
        dauer = time.time() - start
    print(f"{anzahl} Rahmen gesendet in {dauer:.3f} s ({anzahl/dauer:,.0f}/s), plus 1 ungültige Signatur; Schlüssel {kp.pubkey()}")
    return 0

if __name__ == "__main__":
    sys.exit(main())
