#!/usr/bin/env bash
# backup_chrome_bookmarks — copia byte a byte los archivos Bookmarks de perfiles
# Chrome/Chromium a un directorio de backup con timestamp. Preserva el checksum
# interno del archivo sin parsear ni reserializar el JSON.

set -euo pipefail

backup_chrome_bookmarks() {
    # ── defaults ──────────────────────────────────────────────────────────────
    local _user_data_dir=""
    local _profiles=()
    local _backup_dir="${HOME}/.local/share/web_scraping/bookmarks-backups"
    local _dry_run=0

    # ── parse args ─────────────────────────────────────────────────────────────
    _usage() {
        cat >&2 <<'EOF'
Usage: backup_chrome_bookmarks --user-data-dir <dir> [--profile <name>]...
           [--backup-dir <dir>] [--dry-run]

  --user-data-dir   (obligatorio) Raíz de perfiles de Chrome/Chromium.
                    Ej: ~/.config/chromium-cdp
  --profile <name>  Nombre de carpeta de perfil a respaldar (repetible).
                    Si no se pasa ninguno → respalda TODOS los perfiles con
                    un archivo Bookmarks (excluye System Profile).
  --backup-dir <dir> Directorio raíz para backups.
                    Default: ~/.local/share/web_scraping/bookmarks-backups
  --dry-run         Muestra qué copiaría sin tocar nada.

Exit codes:
  0  éxito (o dry-run completado)
  1  error de argumento o validación
EOF
        return 1
    }

    while [[ $# -gt 0 ]]; do
        case "$1" in
            --user-data-dir) _user_data_dir="$2"; shift 2 ;;
            --profile)       _profiles+=("$2");   shift 2 ;;
            --backup-dir)    _backup_dir="$2";    shift 2 ;;
            --dry-run)       _dry_run=1;           shift   ;;
            -h|--help)       _usage; return 0 ;;
            *) echo "backup_chrome_bookmarks: argumento desconocido: $1" >&2; return 1 ;;
        esac
    done

    # ── validaciones ──────────────────────────────────────────────────────────
    if [[ -z "$_user_data_dir" ]]; then
        echo "backup_chrome_bookmarks: --user-data-dir es obligatorio" >&2
        return 1
    fi

    if [[ ! -d "$_user_data_dir" ]]; then
        echo "backup_chrome_bookmarks: directorio no encontrado: ${_user_data_dir}" >&2
        return 1
    fi

    # ── descubrir perfiles si no se pasó ninguno ───────────────────────────────
    if [[ ${#_profiles[@]} -eq 0 ]]; then
        local _candidate
        while IFS= read -r -d '' _candidate; do
            local _pname
            _pname="$(basename "$_candidate")"
            # Excluir System Profile (perfil interno de Chromium sin datos de usuario)
            if [[ "$_pname" == "System Profile" ]]; then
                continue
            fi
            if [[ -f "${_candidate}/Bookmarks" ]]; then
                _profiles+=("$_pname")
            fi
        done < <(find "$_user_data_dir" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z)
    fi

    if [[ ${#_profiles[@]} -eq 0 ]]; then
        echo "backup_chrome_bookmarks: no se encontraron perfiles con archivo Bookmarks en: ${_user_data_dir}" >&2
        return 1
    fi

    # ── timestamp único para este backup ──────────────────────────────────────
    local _ts
    _ts="$(date +%Y%m%dT%H%M%S)"

    # ── procesar perfiles ─────────────────────────────────────────────────────
    # Construir el array de resultados JSON manualmente (sin jq ni python3)
    local _results="["
    local _first=1
    local _profile

    for _profile in "${_profiles[@]}"; do
        local _src="${_user_data_dir}/${_profile}/Bookmarks"

        # Si el perfil no tiene Bookmarks, se omite sin error
        if [[ ! -f "$_src" ]]; then
            continue
        fi

        local _dst="${_backup_dir}/${_ts}/${_profile}/Bookmarks"
        local _bytes
        _bytes="$(wc -c < "$_src")"

        if [[ $_dry_run -eq 1 ]]; then
            echo "backup_chrome_bookmarks: [dry-run] cp -p \"${_src}\" -> \"${_dst}\" (${_bytes} bytes)" >&2
        else
            local _dst_dir
            _dst_dir="$(dirname "$_dst")"
            mkdir -p "$_dst_dir"
            cp -p "$_src" "$_dst"
        fi

        # Escapar comillas dobles en el path por si acaso
        local _src_esc="${_src//\"/\\\"}"
        local _dst_esc="${_dst//\"/\\\"}"
        local _profile_esc="${_profile//\"/\\\"}"

        local _entry
        _entry="$(printf '{"profile":"%s","src":"%s","dst":"%s","bytes":%s}' \
            "$_profile_esc" "$_src_esc" "$_dst_esc" "$_bytes")"

        if [[ $_first -eq 1 ]]; then
            _results+="$_entry"
            _first=0
        else
            _results+=",${_entry}"
        fi
    done

    _results+="]"

    # ── emitir resultado JSON ──────────────────────────────────────────────────
    local _backup_dir_esc="${_backup_dir//\"/\\\"}"
    printf '{"backup_dir":"%s","ts":"%s","profiles":%s}\n' \
        "$_backup_dir_esc" "$_ts" "$_results"
}

# ── auto-ejecución ────────────────────────────────────────────────────────────
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    backup_chrome_bookmarks "$@"
fi
