import time
import numpy as np
from src.data import generate_clustered_data
from src.oracle import get_active_blocks
from src.engine import run_numpy_baseline, run_oxta_hybrid

# --- CONFIGURAÇÃO DO EXPERIMENTO ---
N = 4096           # Escala de LLM (16 Milhões de parâmetros na camada)
BLOCK_SIZE = 128   # Otimizado para Cache L2/L3 e chamadas AVX
SPARSITY = 0.8     # 80% de Esparsidade (Cenário Realista de inferência)
np.random.seed(42)

def main():
    print(f"=== OXTA-CORE v2.2: HYBRID ENGINE (N={N}) ===")

    print("⚙️  Gerando Matrizes Agrupadas...")
    A = generate_clustered_data(N, BLOCK_SIZE, SPARSITY)

    print("⚙️  Preparando Pesos...")
    B = np.random.rand(N, N).astype(np.float32) - 0.5

    start = time.time()
    active_blocks_list = get_active_blocks(A, BLOCK_SIZE)
    t_oracle = time.time() - start

    n_total_blocks = (N // BLOCK_SIZE) ** 2
    n_active = len(active_blocks_list)
    print(f"🔥 Oráculo (Latência): {t_oracle:.4f}s")
    print(f"📊 Blocos Ativos: {n_active}/{n_total_blocks} ({n_active / n_total_blocks:.1%})")

    # --- 4. BENCHMARK ---

    print("\n🚀 Iniciando Corrida (N=4096)...")

    # NumPy Baseline
    print("🏁 NumPy (Dense Force)...")
    t_np = run_numpy_baseline(A, B)
    print(f"   Tempo: {t_np:.4f}s")

    # Oxta Hybrid
    print("⚡ Oxta Hybrid (Sparse Intelligence)...")
    t_oxta = run_oxta_hybrid(A, B, active_blocks_list, BLOCK_SIZE, N)
    print(f"   Tempo: {t_oxta:.4f}s")

    # --- 5. RESULTADOS E VISUALIZAÇÃO ---
    speedup = t_np / t_oxta
    print(f"\n=== VEREDITO FINAL (v2.2) ===")
    print(f"Esparsidade Real: {100 * (1 - n_active / n_total_blocks):.1f}%")
    print(f"Speedup Alcançado: {speedup:.2f}x")

    if t_oxta < t_np:
        print("🏆 VITÓRIA CONFIRMADA: Oxta venceu NumPy!")
        print("Conclusão: A inteligência de seleção de dados superou a latência do Python.")
    else:
        print("Ainda perdendo. Necessário aumentar N ou otimizar o overhead.")

if __name__ == "__main__":
    main()
