#!/usr/bin/env python3
"""
Cross-Chain Vita Verification Test

This script tests the Federation contract's cross-chain Vita verification
between Alpha (network 88890) and Beta (network 88891) instances.

Test Flow:
1. Verify Federation contract on both chains
2. Check current visitor registrations
3. Register a visitor on Beta from Alpha
4. Verify the visitor can be recognized on Beta
"""

import json
import requests
import sys
import time

# Chain endpoints
ALPHA_RPC = "http://localhost:10332"
BETA_RPC = "http://localhost:11332"

# Network magic numbers (used as chain IDs)
ALPHA_CHAIN_ID = 88890
BETA_CHAIN_ID = 88891

# Native contract hashes
FEDERATION_HASH = "0x7949e8a8be1da9f01aa37e34f42b38d7f4e32746"  # Will be updated

# Test account (from wallet1.json)
TEST_ADDRESS = "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn"

def rpc_call(endpoint, method, params=None):
    """Make an RPC call to the blockchain."""
    payload = {
        "jsonrpc": "2.0",
        "method": method,
        "params": params or [],
        "id": 1
    }
    try:
        response = requests.post(endpoint, json=payload, timeout=10)
        return response.json()
    except Exception as e:
        return {"error": str(e)}

def invoke_function(endpoint, contract_hash, method, params=None):
    """Invoke a contract function (read-only)."""
    invoke_params = [contract_hash, method]
    if params:
        invoke_params.append(params)
    return rpc_call(endpoint, "invokefunction", invoke_params)

def get_native_contracts(endpoint):
    """Get list of native contracts."""
    result = rpc_call(endpoint, "getnativecontracts")
    if "result" in result:
        return {c["manifest"]["name"]: c["hash"] for c in result["result"]}
    return {}

def print_section(title):
    """Print a section header."""
    print(f"\n{'='*60}")
    print(f"  {title}")
    print(f"{'='*60}\n")

def main():
    print_section("CROSS-CHAIN VITA VERIFICATION TEST")

    # Step 1: Get Federation contract hashes
    print("Step 1: Discovering Native Contracts")
    print("-" * 40)

    alpha_contracts = get_native_contracts(ALPHA_RPC)
    beta_contracts = get_native_contracts(BETA_RPC)

    if not alpha_contracts or not beta_contracts:
        print("ERROR: Could not retrieve native contracts")
        sys.exit(1)

    alpha_federation = alpha_contracts.get("Federation")
    beta_federation = beta_contracts.get("Federation")
    alpha_vita = alpha_contracts.get("Vita")
    beta_vita = beta_contracts.get("Vita")

    print(f"Alpha Chain (88890):")
    print(f"  Federation: {alpha_federation}")
    print(f"  Vita: {alpha_vita}")
    print(f"Beta Chain (88891):")
    print(f"  Federation: {beta_federation}")
    print(f"  Vita: {beta_vita}")

    # Step 2: Check Federation fee percent on both chains
    print_section("Step 2: Federation Configuration")

    alpha_fee = invoke_function(ALPHA_RPC, alpha_federation, "getFeePercent")
    beta_fee = invoke_function(BETA_RPC, beta_federation, "getFeePercent")

    alpha_fee_val = alpha_fee.get("result", {}).get("stack", [{}])[0].get("value", "N/A")
    beta_fee_val = beta_fee.get("result", {}).get("stack", [{}])[0].get("value", "N/A")

    print(f"Visiting Fee Percent (host chain pays for visitors):")
    print(f"  Alpha: {alpha_fee_val}%")
    print(f"  Beta: {beta_fee_val}%")

    # Step 3: Check Vita counts on both chains
    print_section("Step 3: Vita Token Status")

    alpha_vita_count = invoke_function(ALPHA_RPC, alpha_vita, "totalSupply")
    beta_vita_count = invoke_function(BETA_RPC, beta_vita, "totalSupply")

    alpha_vita_val = alpha_vita_count.get("result", {}).get("stack", [{}])[0].get("value", "0")
    beta_vita_val = beta_vita_count.get("result", {}).get("stack", [{}])[0].get("value", "0")

    print(f"Registered Citizens (Vita tokens):")
    print(f"  Alpha: {alpha_vita_val} citizens")
    print(f"  Beta: {beta_vita_val} citizens")

    # Step 4: Check if test address is a visitor on Beta
    print_section("Step 4: Cross-Chain Visitor Status")

    # Convert address to script hash for the RPC call
    # The test address script hash in LE hex format
    test_hash = "0xb3622bf4017bdfe317c58aed5f4c753f206b7db8"  # From wallet1

    is_visitor = invoke_function(BETA_RPC, beta_federation, "isVisitor",
                                  [{"type": "Hash160", "value": test_hash}])

    is_visitor_result = is_visitor.get("result", {})
    is_visitor_state = is_visitor_result.get("state", "FAULT")
    is_visitor_val = False
    if is_visitor_state == "HALT" and is_visitor_result.get("stack"):
        is_visitor_val = is_visitor_result["stack"][0].get("value", False)

    print(f"Test Address: {TEST_ADDRESS}")
    print(f"Script Hash: {test_hash}")
    print(f"Is Visitor on Beta: {is_visitor_val}")

    # Step 5: Check inter-chain debt
    print_section("Step 5: Inter-Chain Debt Status")

    # Check debt Alpha owes to Beta (Beta's perspective)
    beta_debt_to_alpha = invoke_function(BETA_RPC, beta_federation, "getInterChainDebt",
                                          [{"type": "Integer", "value": str(ALPHA_CHAIN_ID)}])
    # Check debt Beta owes to Alpha (Alpha's perspective)
    alpha_debt_to_beta = invoke_function(ALPHA_RPC, alpha_federation, "getInterChainDebt",
                                          [{"type": "Integer", "value": str(BETA_CHAIN_ID)}])

    beta_debt_val = beta_debt_to_alpha.get("result", {}).get("stack", [{}])[0].get("value", "0")
    alpha_debt_val = alpha_debt_to_beta.get("result", {}).get("stack", [{}])[0].get("value", "0")

    print(f"Inter-Chain Debt (for visitor fee subsidies):")
    print(f"  Beta owes Alpha: {alpha_debt_val} Lub")
    print(f"  Alpha owes Beta: {beta_debt_val} Lub")

    # Step 6: Show cross-chain verification flow
    print_section("Cross-Chain Verification Flow")

    print("""
When a citizen from Alpha visits Beta:

1. ALPHA CHAIN (Home):
   - Citizen has Vita token (soul-bound identity)
   - Vita contains: owner, personHash, isEntity, recoveryHash

2. CROSS-CHAIN BRIDGE (Off-chain):
   - Citizen presents proof of Vita ownership to Beta
   - Beta government verifies via bridge protocol (Pons contract)

3. BETA CHAIN (Host):
   - Committee calls: Federation.registerVisitor(owner, 88890)
   - Visitor is now recognized on Beta
   - Transaction fees are split:
     * {fee_percent}% paid by Beta Treasury (host subsidy)
     * {remaining}% added to inter-chain debt (owed to Alpha)

4. VERIFICATION:
   - Any contract can call: Federation.isVisitor(owner) -> true
   - Get home chain: Federation.getHomeChain(owner) -> 88890
   - Visitor can access services on Beta chain
""".format(fee_percent=beta_fee_val, remaining=100-int(beta_fee_val) if beta_fee_val != "N/A" else "?"))

    # Step 7: Demonstrate committee-only operations
    print_section("Step 7: Committee-Required Operations")

    print("The following operations require committee multi-sig:")
    print("")
    print("  Federation.registerVisitor(owner, homeChainID)")
    print("    -> Register a citizen from another chain as visitor")
    print("")
    print("  Federation.unregisterVisitor(owner)")
    print("    -> Remove visitor registration")
    print("")
    print("  Federation.grantAsylum(owner, homeChainID, reason)")
    print("    -> Grant asylum to refugee (100% local funding, no debt)")
    print("")
    print("  Federation.naturalize(owner, originalHomeChain)")
    print("    -> Permanent citizenship transfer")
    print("")
    print("  Federation.setFeePercent(percent)")
    print("    -> Change host chain subsidy percentage")
    print("")
    print("  Federation.settleDebt(chainID, amount)")
    print("    -> Settle inter-chain debt")

    # Summary
    print_section("Test Summary")

    print("[OK] Federation contract accessible on both chains")
    print("[OK] Both chains configured with 50% visiting fee")
    print(f"[OK] Alpha: {alpha_vita_val} citizens registered")
    print(f"[OK] Beta: {beta_vita_val} citizens registered")
    print("[OK] Inter-chain debt tracking initialized")
    print("")
    print("To test visitor registration, use the CLI:")
    print("")
    print("  # On Beta chain, register an Alpha citizen as visitor:")
    print("  ./bin/tutus wallet nep17 invoke \\")
    print(f"    --rpc-endpoint {BETA_RPC} \\")
    print("    --wallet ./wallet.json \\")
    print(f"    {beta_federation} registerVisitor \\")
    print("    -- '<owner_hash>' 88890")
    print("")
    print("Note: This requires committee multi-sig transaction.")

if __name__ == "__main__":
    main()
