#!/usr/bin/env python3
"""Devnet custodial treasury setup (ADR-0015, US-032).

Creates the mock-USDT SPL mint (6 decimals, matching real USDT) and the
treasury associated token account on Solana devnet, then prints/writes the
.env.devnet values. Real USDT exists only on mainnet — the mint address is
config, so mainnet cutover is a config change.

Usage:
  python scripts/devnet_setup.py                                  # full setup
  python scripts/devnet_setup.py --mint <ADDR>                    # reuse existing mint
  python scripts/devnet_setup.py --mint <ADDR> --mint-to <WALLET> --amount 25
"""

import argparse
import json
import os
import sys
import time

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "packages", "contracts"))

from solders.keypair import Keypair  # noqa: E402

from meshnet_contracts.solana_adapter import SolanaCustodialTreasury  # noqa: E402

DEFAULT_KEYPAIR = os.path.expanduser("~/.config/solana/meshnet-treasury.json")
DEFAULT_RPC = "https://api.devnet.solana.com"
# placeholder mint for bootstrapping the adapter before the real mint exists
_SYSTEM_PROGRAM = "11111111111111111111111111111111"


def _load_or_create_keypair(path: str) -> Keypair:
    if os.path.exists(path):
        with open(path, encoding="utf-8") as fh:
            return Keypair.from_bytes(bytes(json.load(fh)))
    keypair = Keypair()
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with open(path, "w", encoding="utf-8") as fh:
        json.dump(list(bytes(keypair)), fh)
    os.chmod(path, 0o600)
    print(f"generated treasury keypair: {path}")
    return keypair


def _ensure_sol(treasury: SolanaCustodialTreasury, minimum_sol: float = 0.5) -> None:
    balance = treasury.get_sol_balance()
    if balance >= minimum_sol:
        print(f"treasury SOL balance: {balance:.4f}")
        return
    print(f"airdropping 2 SOL to {treasury.treasury_wallet} (balance {balance:.4f})…")
    signature = treasury.request_airdrop(2.0)
    for _ in range(30):
        time.sleep(2)
        if treasury.get_sol_balance() >= minimum_sol:
            print("airdrop confirmed")
            return
    sys.exit(
        f"airdrop {signature} not confirmed — devnet faucet may be rate-limited; retry later"
    )


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--rpc-url", default=DEFAULT_RPC)
    parser.add_argument("--keypair", default=DEFAULT_KEYPAIR, help="Treasury keypair path")
    parser.add_argument("--mint", default=None, help="Reuse an existing mock-USDT mint address")
    parser.add_argument("--mint-to", default=None, metavar="WALLET",
                        help="Mint mock USDT to a client wallet (creates their token account)")
    parser.add_argument("--amount", type=float, default=100.0, help="Amount for --mint-to")
    parser.add_argument("--env-out", default=".env.devnet", help="Env file to write")
    args = parser.parse_args()

    keypair = _load_or_create_keypair(args.keypair)
    bootstrap = SolanaCustodialTreasury(args.rpc_url, args.mint or _SYSTEM_PROGRAM, keypair)
    print(f"treasury wallet: {bootstrap.treasury_wallet}")
    _ensure_sol(bootstrap)

    if args.mint:
        treasury = SolanaCustodialTreasury(args.rpc_url, args.mint, keypair)
        mint_address = args.mint
        print(f"using existing mock-USDT mint: {mint_address}")
    else:
        treasury, mint_address = bootstrap.create_mock_usdt_mint()
        print(f"created mock-USDT mint (6 decimals): {mint_address}")
        time.sleep(2)  # let the mint transaction confirm before creating ATAs

    treasury.ensure_token_account(treasury.treasury_wallet)
    print(f"treasury token account: {treasury.treasury_token_account}")

    if args.mint_to:
        signature = treasury.mint_mock_usdt(args.mint_to, args.amount)
        print(f"minted {args.amount} mock USDT to {args.mint_to} (tx {signature})")

    env = (
        f"MESHNET_SOLANA_RPC_URL={args.rpc_url}\n"
        f"MESHNET_USDT_MINT={mint_address}\n"
        f"MESHNET_TREASURY_KEYPAIR={args.keypair}\n"
        f"MESHNET_TREASURY_WALLET={treasury.treasury_wallet}\n"
        f"MESHNET_TREASURY_TOKEN_ACCOUNT={treasury.treasury_token_account}\n"
    )
    with open(args.env_out, "w", encoding="utf-8") as fh:
        fh.write(env)
    print(f"\nwrote {args.env_out}:\n{env}")


if __name__ == "__main__":
    main()
