"""Lee un secreto del gestor de contrasenas `pass` (passwordstore.org).

Ejecuta `pass show <path>` como subproceso (lista de args, nunca shell=True) y
devuelve la linea solicitada del secreto. Por convencion de pass, la primera
linea es la contrasena y las lineas siguientes son metadata (usuario, URL,
notas, etc.).

El valor devuelto es sensible: esta funcion NUNCA lo logea. El caller es
responsable de tratarlo como secreto (no imprimirlo, no persistirlo en claro).
"""

import subprocess


def pass_get_secret(path: str, *, line: int = 1, timeout_s: float = 10.0) -> dict:
    """Lee una linea de un secreto del password store (pass).

    Args:
        path: ruta del secreto dentro del store (p.ej. "gitea/dataforge-git-token").
            Es el argumento que recibiria `pass show <path>`.
        line: numero de linea a devolver, 1-indexed. line=1 (default) es la
            primera linea = la contrasena por convencion de pass. line=N
            devuelve la linea N para metadata multilinea.
        timeout_s: timeout del subproceso en segundos.

    Returns:
        Dict. En exito: ``{"status": "ok", "value": str}`` con la linea pedida
        sin el salto de linea final. En error (sin lanzar):
        ``{"status": "error", "error": str}`` para: pass no instalado, entry
        inexistente / fallo de pass (returncode != 0), o linea fuera de rango.
    """
    try:
        proc = subprocess.run(
            ["pass", "show", path],
            capture_output=True,
            text=True,
            timeout=timeout_s,
        )
    except FileNotFoundError:
        return {"status": "error", "error": "pass not installed"}
    except subprocess.TimeoutExpired:
        return {"status": "error", "error": f"pass timed out after {timeout_s}s"}

    if proc.returncode != 0:
        return {"status": "error", "error": (proc.stderr or "").strip()}

    # `pass show` termina con un salto de linea; splitlines lo absorbe.
    lines = proc.stdout.splitlines()
    if line < 1 or line > len(lines):
        return {"status": "error", "error": f"line {line} out of range"}

    return {"status": "ok", "value": lines[line - 1]}
