"""Tests para enrich_person_passive.

Las funciones compuestas (guess_email_formats, enumerate_username_sites,
build_search_dorks) se monkeypatchean. Solo se verifica la orquestacion: que
itera por dominios/usernames, deduplica emails, usa dominios comunes por
defecto y genera (sin ejecutar) los dorks.
"""

import importlib
import os
import sys

import pytest

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

from cybersecurity import enrich_person_passive

# El paquete re-exporta la funcion bajo el mismo nombre que el submodulo; para
# parchear los globals del modulo lo tomamos via importlib.
mod = importlib.import_module("cybersecurity.enrich_person_passive")


def _patch(monkeypatch, *, emails_fn=None, usernames_fn=None, dorks_fn=None):
    monkeypatch.setattr(
        mod,
        "guess_email_formats",
        emails_fn or (lambda n, a, d: [f"{n.lower()}.{a.lower()}@{d}", f"{n[0].lower()}{a.lower()}@{d}"]),
    )
    monkeypatch.setattr(
        mod,
        "enumerate_username_sites",
        usernames_fn or (lambda u: [{"site": "github", "url": f"https://github.com/{u}", "exists": True}]),
    )
    monkeypatch.setattr(
        mod,
        "build_search_dorks",
        dorks_fn or (lambda target, tipo: [f'"{target}" {tipo}', f'intext:"{target}"']),
    )


def test_golden_compone_emails_usernames_y_dorks(monkeypatch):
    _patch(monkeypatch)

    res = enrich_person_passive(
        "Juan", "Perez",
        dominios=["organic-machine.com"],
        usernames=["jperez", "juanp"],
    )

    assert res["email_candidates"] == [
        "juan.perez@organic-machine.com",
        "jperez@organic-machine.com",
    ]
    assert [u["username"] for u in res["username_hits"]] == ["jperez", "juanp"]
    assert res["username_hits"][0]["hits"][0]["site"] == "github"
    assert res["dorks"] == ['"Juan Perez" persona', 'intext:"Juan Perez"']


def test_sin_dominios_usa_comunes(monkeypatch):
    seen_domains = []

    def emails(n, a, d):
        seen_domains.append(d)
        return [f"{n}@{d}"]

    _patch(monkeypatch, emails_fn=emails)

    res = enrich_person_passive("Ana", "Lopez")

    assert seen_domains == ["gmail.com", "outlook.com"]
    assert res["email_candidates"] == ["Ana@gmail.com", "Ana@outlook.com"]


def test_sin_usernames_no_comprueba(monkeypatch):
    called = []
    _patch(monkeypatch, usernames_fn=lambda u: called.append(u) or [])

    res = enrich_person_passive("Ana", "Lopez", dominios=["x.com"])

    assert res["username_hits"] == []
    assert called == []  # enumerate_username_sites no se invoca


def test_nombre_y_apellidos_vacios_lanza(monkeypatch):
    _patch(monkeypatch)
    with pytest.raises(ValueError):
        enrich_person_passive("", "   ")


def test_emails_deduplicados(monkeypatch):
    # Dos dominios distintos que devuelven el mismo email -> debe deduplicar.
    _patch(monkeypatch, emails_fn=lambda n, a, d: ["dup@same.com", "dup@same.com"])

    res = enrich_person_passive("Juan", "Perez", dominios=["a.com", "b.com"])

    assert res["email_candidates"] == ["dup@same.com"]
