"""Lanza Chromium en un perfil del catalogo osint_db y expone sus cuentas/secret_refs.

Wrapper que compone `browser_profile_show` (para leer la metadata del perfil y sus
cuentas desde el service osint_db) y luego lanza Chromium en ese perfil. Devuelve las
cuentas con sus `secret_ref` (REFERENCIAS a secretos, nunca el password) para que el
operador sepa que credenciales usar.

GOTCHAS de este entorno (Linux nativo de enmanuel):
- El wrapper `/usr/bin/chromium` ya inyecta `--user-data-dir=$HOME/.config/chromium-cdp`
  y `--remote-debugging-port=9222` via `/etc/chromium.d/cdp`. Por eso, si el
  `user_data_dir` resuelto ES ese default, NO se pasa `--user-data-dir` (se hereda del
  wrapper); si es OTRO directorio, se pasa explicito.
- Lanzar chromium directamente como hijo da exit-144 en este entorno. Se lanza SIEMPRE
  via `systemd-run --user --scope --` (proceso aislado), en background, sin esperar.

Funcion impura: hace red (HTTP al service) y lanza un proceso. No lanza excepciones;
devuelve un dict de estado. Con `dry_run=True` no abre nada (devuelve el comando).
"""

import os
import subprocess

from browser.browser_profile_show import browser_profile_show

# Default del wrapper /etc/chromium.d/cdp en esta maquina (se compara expandido).
_DEFAULT_USER_DATA_DIR = os.path.expanduser("~/.config/chromium-cdp")


def browser_profile_open(
    profile_dir: str,
    url: str | None = None,
    base_url: str = "http://127.0.0.1:8771",
    dry_run: bool = False,
) -> dict:
    """Lanza Chromium en el perfil indicado y devuelve sus cuentas/secret_refs.

    Args:
        profile_dir: nombre del directorio real del perfil Chromium (ej. "Profile 1",
            "osint_01"). Debe existir en el catalogo osint_db.
        url: URL a abrir al arrancar (ej. "https://mail.google.com"). None -> sin URL.
        base_url: base del service osint_db. Default http://127.0.0.1:8771.
        dry_run: si True, NO lanza nada; devuelve el comando que lanzaria. Util para test
            y para revisar el comando antes de abrir el navegador.

    Returns:
        Caso dry_run ok: {"status":"ok", "profile_dir": str, "cmd": list[str] (argv que
            se lanzaria), "accounts": list de dicts {service, identity, secret_ref, role}}.
        Caso real ok: {"status":"ok", "profile_dir": str, "launched": True,
            "cmd": list[str], "accounts": list de dicts {service, identity, secret_ref, role}}.
        Caso perfil no existe / service caido: {"status":"error", "error": str} (no lanza).
    """
    try:
        meta = browser_profile_show(profile_dir, base_url=base_url)
        if meta.get("status") != "ok":
            # Perfil inexistente o service caido: propaga el error sin lanzar nada.
            return meta

        profile = meta.get("profile", {})
        raw_accounts = meta.get("accounts", [])
        accounts = [
            {
                "service": a.get("service"),
                "identity": a.get("identity"),
                "secret_ref": a.get("secret_ref"),
                "role": a.get("role"),
            }
            for a in raw_accounts
        ]

        # Resolver user_data_dir: el de la fila si no esta vacio; si no, el default del wrapper.
        row_udd = (profile.get("user_data_dir") or "").strip()
        resolved_udd = os.path.expanduser(row_udd) if row_udd else _DEFAULT_USER_DATA_DIR

        chromium_args = ["chromium", f'--profile-directory={profile_dir}']
        # Solo pasar --user-data-dir si NO es el default del wrapper (que ya lo inyecta).
        if os.path.normpath(resolved_udd) != os.path.normpath(_DEFAULT_USER_DATA_DIR):
            chromium_args.append(f"--user-data-dir={resolved_udd}")
        if url:
            chromium_args.append(url)

        # Lanzamiento aislado para evitar exit-144 (ver gotcha del modulo).
        cmd = ["systemd-run", "--user", "--scope", "--", *chromium_args]

        if dry_run:
            return {
                "status": "ok",
                "profile_dir": profile_dir,
                "cmd": cmd,
                "accounts": accounts,
            }

        # Background, sin esperar: no bloquear al operador ni capturar el navegador.
        subprocess.Popen(
            cmd,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            start_new_session=True,
        )

        return {
            "status": "ok",
            "profile_dir": profile_dir,
            "launched": True,
            "cmd": cmd,
            "accounts": accounts,
        }
    except Exception as e:  # noqa: BLE001 - contrato: nunca lanzar
        return {"status": "error", "error": f"{type(e).__name__}: {e}"}


if __name__ == "__main__":
    # Smoke contra un puerto muerto: el service caido -> browser_profile_show falla,
    # browser_profile_open propaga el error sin abrir navegador.
    res = browser_profile_open("Profile 1", url="https://example.com",
                               base_url="http://127.0.0.1:1", dry_run=True)
    assert res["status"] == "error", res
    print("browser_profile_open smoke OK (service caido -> status error, sin lanzar)")
    print(f"  {res}")
