#!/usr/bin/env python3
"""
Liste TOUTES les fonctions du contrat Diamond
"""

from web3 import Web3
import requests
import json

APOLLOX_CONTRACT = "0x1b6F2d3844C6ae7D56ceb3C3643b9060ba28FEb0"
BSC_RPC = "https://bsc-dataseed.binance.org/"

w3 = Web3(Web3.HTTPProvider(BSC_RPC))

# Diamond Loupe ABI
DIAMOND_LOUPE_ABI = [{
    "name": "facets",
    "outputs": [{
        "components": [
            {"name": "facetAddress", "type": "address"},
            {"name": "functionSelectors", "type": "bytes4[]"}
        ],
        "internalType": "struct IDiamondLoupe.Facet[]",
        "name": "facets_",
        "type": "tuple[]"
    }],
    "stateMutability": "view",
    "type": "function"
}]


def get_abi_from_bscscan(address: str) -> list:
    """Récupère l'ABI depuis BSCScan API"""
    url = "https://api.bscscan.com/api"
    params = {
        'module': 'contract',
        'action': 'getabi',
        'address': address,
        'apikey': 'YourApiKeyToken'
    }

    try:
        response = requests.get(url, params=params, timeout=10)
        data = response.json()

        if data.get('status') == '1':
            return json.loads(data['result'])
        return []
    except:
        return []


def main():
    print("=" * 80)
    print("📋 LISTE COMPLÈTE DES FONCTIONS - APOLLOX CONTRACT")
    print("=" * 80)
    print()

    contract = w3.eth.contract(
        address=Web3.to_checksum_address(APOLLOX_CONTRACT),
        abi=DIAMOND_LOUPE_ABI
    )

    # Récupérer tous les facets
    facets = contract.functions.facets().call()

    print(f"Total facets: {len(facets)}\n")

    # Collecter tous les selectors
    all_selectors = {}
    for facet in facets:
        facet_addr = facet[0]
        selectors = facet[1]

        for sel in selectors:
            all_selectors[sel.hex()] = facet_addr

    print(f"Total fonctions: {len(all_selectors)}\n")

    # Chercher les ABIs des facets pour identifier les noms
    print("🔍 Recherche des noms de fonctions...\n")

    # Fonctions communes qu'on peut détecter
    known_functions = {
        # Trading
        '4584eff6': 'openMarketTrade',
        '421cdddf': 'closeTrade',
        '058ddbe5': 'addMargin',
        '44a9ca3f': 'updateTradeTpAndSl',

        # Positions
        '0eda5be8': 'getPositionsV2',
        'a81a5d72': 'getPositionByHashV2',

        # History (à chercher)
        '8d933429': 'getOrderAndTradeHistoryV2',

        # Diamond Loupe
        '7a0ed627': 'facets',
        '52ef6b2c': 'facetFunctionSelectors',
        'cdffacc6': 'facetAddresses',
        '01ffc9a7': 'supportsInterface',

        # Ownership
        '8da5cb5b': 'owner',
        'f2fde38b': 'transferOwnership',
    }

    # Afficher toutes les fonctions
    history_selectors = []
    position_selectors = []

    for sel, facet_addr in sorted(all_selectors.items()):
        func_name = known_functions.get(sel, '???')

        # Identifier si c'est potentiellement une fonction history
        if 'history' in func_name.lower() or 'order' in func_name.lower():
            history_selectors.append((sel, func_name, facet_addr))
            marker = "📜 HISTORY"
        elif 'position' in func_name.lower() or 'trade' in func_name.lower():
            position_selectors.append((sel, func_name, facet_addr))
            marker = "📊 POSITION"
        else:
            marker = "  "

        if func_name != '???':
            print(f"{marker} {sel}: {func_name}")
            print(f"           Facet: {facet_addr}")

    # Résumé
    print("\n" + "=" * 80)
    print("📊 RÉSUMÉ")
    print("=" * 80)
    print(f"Total fonctions: {len(all_selectors)}")
    print(f"History functions: {len(history_selectors)}")
    print(f"Position functions: {len(position_selectors)}")

    if history_selectors:
        print("\n📜 HISTORY FUNCTIONS:")
        for sel, name, facet in history_selectors:
            print(f"   {sel}: {name}")
            print(f"      Facet: {facet}")
    else:
        print("\n❌ AUCUNE FONCTION HISTORY TROUVÉE")

    if position_selectors:
        print("\n📊 POSITION FUNCTIONS:")
        for sel, name, facet in position_selectors:
            print(f"   {sel}: {name}")
            print(f"      Facet: {facet}")

    # Tentative de récupérer l'ABI complet depuis BSCScan
    print("\n" + "=" * 80)
    print("🔍 RECHERCHE ABI SUR BSCSCAN")
    print("=" * 80)

    abi = get_abi_from_bscscan(APOLLOX_CONTRACT)
    if abi:
        print(f"✅ ABI récupéré: {len(abi)} entrées\n")

        # Chercher fonctions avec history dans le nom
        history_funcs = [
            func for func in abi
            if func.get('type') == 'function' and
            ('history' in func.get('name', '').lower() or 'order' in func.get('name', '').lower())
        ]

        if history_funcs:
            print("📜 FONCTIONS HISTORY DANS L'ABI:")
            for func in history_funcs:
                print(f"   {func['name']}")

                # Calculer selector
                inputs = ','.join(inp['type'] for inp in func.get('inputs', []))
                sig = f"{func['name']}({inputs})"
                selector = Web3.keccak(text=sig)[:4].hex()
                print(f"      Selector: {selector}")

                # Vérifier si présent dans le contrat
                if selector in all_selectors:
                    print(f"      ✅ PRÉSENT dans facet {all_selectors[selector]}")
                else:
                    print(f"      ❌ NON PRÉSENT dans le contrat")
                print()
        else:
            print("❌ Aucune fonction history dans l'ABI BSCScan")
    else:
        print("❌ Impossible de récupérer l'ABI depuis BSCScan")


if __name__ == '__main__':
    main()
