# keepass_dump
# ------------
# Exporta toda la BD KeePassXC como array JSON. Una sola apertura del .kdbx.
# Cada elemento: {path, title, username, password, url, notes}.
#
# REQUIERE:
#   - keepassxc-cli instalado
#   - python3 (stdlib xml.etree)
#   - KEEPASS_DB (env): ruta absoluta al .kdbx
#   - master password en pass o env KEEPASS_PASSWORD
#
# USO (sourced):
#   source keepass_dump.sh
#   data=$(keepass_dump)
#   echo "$data" | jq '.[] | select(.path | startswith("Servers/"))'

keepass_dump() {
    local db="${KEEPASS_DB:-}"
    if [ -z "$db" ] || [ ! -f "$db" ]; then
        echo "keepass_dump: KEEPASS_DB no valida: $db" >&2
        return 1
    fi

    local master
    if [ -n "${KEEPASS_PASSWORD:-}" ]; then
        master="$KEEPASS_PASSWORD"
    else
        master=$(pass show "${KEEPASS_MASTER_ENTRY:-meta/keepassxc-master}" 2>/dev/null | head -n1)
        if [ -z "$master" ]; then
            echo "keepass_dump: no master pass" >&2
            return 1
        fi
    fi

    local xml
    xml=$(printf '%s\n' "$master" | keepassxc-cli export -q -f xml "$db" 2>/dev/null)
    if [ $? -ne 0 ] || [ -z "$xml" ]; then
        echo "keepass_dump: export xml fallo (master incorrecta?)" >&2
        return 1
    fi

    printf '%s' "$xml" | python3 -c '
import sys, json, re
import xml.etree.ElementTree as ET

root = ET.fromstring(sys.stdin.read())
out = []

def clean(s):
    if not s:
        return ""
    s = s.strip().rstrip("/")
    s = s.replace("/", "_")
    s = re.sub(r"\s+", "_", s)
    s = re.sub(r"_+", "_", s)
    s = s.strip("_")
    return s

def walk(group, path):
    name_el = group.find("Name")
    raw_name = name_el.text if name_el is not None and name_el.text else ""
    name = clean(raw_name)
    new_path = path + [name] if name and name != "Root" else path
    for entry in group.findall("Entry"):
        rec = {}
        for s in entry.findall("String"):
            k_el = s.find("Key")
            v_el = s.find("Value")
            if k_el is None or k_el.text is None:
                continue
            rec[k_el.text] = (v_el.text if v_el is not None and v_el.text else "")
        title = clean(rec.get("Title", ""))
        full = "/".join(new_path + [title]) if title else "/".join(new_path)
        out.append({
            "path": full,
            "title": title,
            "username": rec.get("UserName", ""),
            "password": rec.get("Password", ""),
            "url": rec.get("URL", ""),
            "notes": rec.get("Notes", ""),
        })
    for sub in group.findall("Group"):
        walk(sub, new_path)

root_grp = root.find("Root/Group")
if root_grp is not None:
    walk(root_grp, [])

print(json.dumps(out, ensure_ascii=False))
'
}
