"""Benchmark v2 — GLiNER2 (Apache 2.0, NER+RE joint) vs stack actual.

Genera benchmark_v2.json con resultados sobre 4 corpora:
  - es_corporate_short (notebook 02 baseline)
  - es_corporate_long (extension a ~30 frases)
  - es_osint (castellano, ciberseguridad — NUEVO)
  - en_corporate (control idioma)

Para cada corpus, corre GLiNER2 con el schema joint y registra:
  ents, rels, time, calidad manual a posteriori.
"""
from __future__ import annotations

import json
import os
import sys
import time
import warnings
from pathlib import Path

warnings.filterwarnings("ignore")
os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")

HERE = Path(__file__).resolve().parent
_pf = "/home/lucas/fn_registry/python/functions"
sys.path = [p for p in sys.path if not p.startswith(_pf + "/")]
if _pf not in sys.path:
    sys.path.insert(0, _pf)

from gliner2 import GLiNER2

CORPUS = {
    "es_corporate_short": (
        "Pablo Isla, expresidente de Inditex, ha sido nombrado consejero de Telefonica. "
        "La operacion fue anunciada por el presidente Jose Maria Alvarez-Pallete en Madrid el pasado lunes. "
        "Inditex factura mas de 30.000 millones anuales y tiene su sede en Arteixo, A Coruna. "
        "En paralelo, Iberdrola y Endesa firmaron un acuerdo de colaboracion en proyectos eolicos en Galicia. "
        "El presidente de Iberdrola, Ignacio Galan, se reunio con la CEO de Endesa, Marina Serrano, en Bilbao. "
        "El acuerdo movilizara 2.000 millones de euros en cinco anos. "
        "El BBVA, presidido por Carlos Torres, mostro interes en participar en la financiacion del proyecto. "
        "Su sede central esta en Bilbao."
    ),
    "es_corporate_long": (
        # 30 frases — generadas para test de chunking y memoria
        "Pablo Isla, expresidente de Inditex, ha sido nombrado consejero de Telefonica. "
        "La operacion fue anunciada por el presidente Jose Maria Alvarez-Pallete en Madrid el pasado lunes. "
        "Inditex factura mas de 30.000 millones anuales y tiene su sede en Arteixo, A Coruna. "
        "Amancio Ortega, fundador de Inditex, sigue siendo el principal accionista. "
        "Su hija Marta Ortega ha asumido la presidencia ejecutiva del grupo en 2022. "
        "Zara, marca emblema de Inditex, opera en mas de 90 paises. "
        "Telefonica anuncio una alianza estrategica con Microsoft para servicios cloud. "
        "Satya Nadella, CEO de Microsoft, visito la sede de Telefonica en Distrito Telefonica. "
        "BBVA, presidido por Carlos Torres, ha completado la integracion de Sabadell tras la fusion. "
        "Onur Genc, consejero delegado del banco, lideró el proceso desde Bilbao. "
        "Banco Santander, dirigido por Ana Botin, sigue siendo el primer banco espanol por capitalizacion. "
        "Hector Grisi es el CEO global de Santander desde enero de 2023. "
        "CaixaBank tiene su sede operativa en Valencia desde 2017, presidida por Jose Ignacio Goirigolzarri. "
        "Iberdrola, liderada por Ignacio Galan, opera en EEUU a traves de Avangrid. "
        "Endesa, filial de la italiana Enel, tiene como CEO a Marina Serrano. "
        "El acuerdo entre Iberdrola y Endesa movilizara 2.000 millones de euros en proyectos eolicos en Galicia. "
        "Repsol, dirigida por Josu Jon Imaz, ha vendido su filial de Mexico a la australiana Macquarie. "
        "Antonio Brufau preside el consejo de administracion de Repsol desde hace mas de una decada. "
        "Acciona, presidida por Jose Manuel Entrecanales, ha cerrado un contrato en Australia por 600 millones. "
        "Ferrovial, presidida por Rafael del Pino, traslado su sede a Holanda en 2022. "
        "ACS, presidida por Florentino Perez, sigue siendo lider mundial en construccion de infraestructuras. "
        "Naturgy, antes Gas Natural, esta presidida por Francisco Reynes desde Madrid. "
        "Indra ha nombrado a Marc Murtra como nuevo presidente tras la salida de Fernando Abril-Martorell. "
        "Telefonica anuncio el cierre de su division de medios y la venta de Telxius a American Tower. "
        "El Banco de Espana, gobernado por Pablo Hernandez de Cos, advirtio sobre los riesgos de inflacion. "
        "Luis de Guindos, vicepresidente del BCE, fue ministro de Economia en el gobierno de Mariano Rajoy. "
        "Calvin Souther Fuller, fundador de SunPower, vendio la empresa al grupo TotalEnergies. "
        "Patrick Pouyanne, CEO de TotalEnergies, anuncio inversiones en renovables en Espana. "
        "Iberdrola firma con Amazon un PPA de 15 anos para suministrar energia eolica. "
        "Andy Jassy, CEO de Amazon, agradecio el acuerdo en una nota publica desde Seattle."
    ),
    "es_osint": (
        # OSINT en castellano — ciberseguridad
        "El 15 de agosto de 2024, el grupo APT-29 (atribuido a Rusia) lanzo una campana de phishing contra empresas energeticas espanolas. "
        "El servidor de comando y control 185.220.101.45 conectaba con sistemas internos de Iberdrola via TLS. "
        "El malware utilizado, identificado como CozyBear, exploto la vulnerabilidad CVE-2024-21412 en Microsoft Defender. "
        "El operador @phantomzero reivindico el ataque en un foro de la dark web alojado en hxxps://malwareops[.]biz/control. "
        "El analista Carlos Garcia, del CCN-CERT, publico un informe tecnico con el hash SHA-256 a3f5e8c9b1d2e3f4a5b6c7d8e9f0a1b2 del binario malicioso. "
        "Telefonica Tech alerto a sus clientes sobre indicadores de compromiso adicionales en el dominio cloudfront-cdn[.]net."
    ),
    "en_corporate_short": (
        "Pablo Isla, the former chairman of Inditex, has been appointed as a director of Telefonica. "
        "The announcement was made by Jose Maria Alvarez-Pallete, the chairman of Telefonica, in Madrid last Monday. "
        "Inditex has its headquarters in Arteixo, A Coruna. "
        "BBVA, chaired by Carlos Torres, has its headquarters in Bilbao."
    ),
}

ENTITY_LABELS = {
    "general":  ["person", "organization", "location"],
    "osint_es": ["persona", "organizacion", "ubicacion", "ip_address", "dominio", "url", "username", "vulnerabilidad", "malware", "hash"],
    "osint_en": ["person", "organization", "location", "ip_address", "domain", "url", "username", "vulnerability", "malware", "hash"],
}

RELATION_LABELS = {
    "corporate":  ["works_at", "located_in", "appointed_as", "ceo_of", "president_of",
                   "headquartered_in", "subsidiary_of", "parent_company", "founded_by",
                   "agreement_with", "acquired", "succeeded_by"],
    "osint_es": ["targets", "controlled_by", "hosted_at", "exploits", "uses",
                 "attributed_to", "communicates_with", "indicator_of"],
    "osint_en": ["targets", "controlled_by", "hosted_at", "exploits", "uses",
                 "attributed_to", "communicates_with", "indicator_of"],
}


def run_corpus(model: GLiNER2, corpus_key: str, text: str) -> dict:
    if "osint" in corpus_key:
        ent_lbl = ENTITY_LABELS["osint_es"] if "es_" in corpus_key else ENTITY_LABELS["osint_en"]
        rel_lbl = RELATION_LABELS["osint_es"] if "es_" in corpus_key else RELATION_LABELS["osint_en"]
    else:
        ent_lbl = ENTITY_LABELS["general"]
        rel_lbl = RELATION_LABELS["corporate"]

    schema = (
        model.create_schema()
        .entities(ent_lbl)
        .relations(rel_lbl)
    )
    t0 = time.time()
    result = model.extract(text, schema=schema)
    elapsed = time.time() - t0

    n_ents = sum(len(v) for v in result.get("entities", {}).values())
    n_rels = sum(len(v) for v in result.get("relation_extraction", {}).values())
    return {
        "n_chars": len(text),
        "n_words": len(text.split()),
        "elapsed_s": round(elapsed, 3),
        "n_entities": n_ents,
        "n_relations": n_rels,
        "entities": result.get("entities", {}),
        "relations": result.get("relation_extraction", {}),
        "ent_labels": ent_lbl,
        "rel_labels": rel_lbl,
    }


def main():
    print("[load] GLiNER2 large...")
    t0 = time.time()
    m = GLiNER2.from_pretrained("fastino/gliner2-large-v1")
    print(f"[load] {time.time()-t0:.1f}s\n")

    results = {}
    for k, text in CORPUS.items():
        print(f"[corpus] {k}  ({len(text)} chars, {len(text.split())} words)")
        r = run_corpus(m, k, text)
        results[k] = r
        print(f"  → {r['n_entities']} ents, {r['n_relations']} rels, {r['elapsed_s']}s\n")

    out = HERE / "benchmark_v2.json"
    out.write_text(json.dumps(results, indent=2, ensure_ascii=False))
    print(f"[saved] {out}")
    return results


if __name__ == "__main__":
    main()
