#!/usr/bin/env bash
# verify.sh — (re)verifica dispositivos E2EE de agentes Matrix
#
# Genera/sube cross-signing keys y firma el device de cada agente.
# Usa el MISMO crypto store que el agente para que las keys queden disponibles.
#
# Uso:
#   ./dev-scripts/agent/verify.sh                  # verifica todos los habilitados con E2EE
#   ./dev-scripts/agent/verify.sh assistant-bot    # verifica uno específico

source "$(dirname "$0")/../_common.sh"
load_env

TARGET="${1:-}"

# ── YAML helpers (simple grep-based, no deps) ────────────────────────────

yaml_val() {
  # Extract a simple YAML value: yaml_val file "key"
  # Handles both quoted and unquoted values.
  local file="$1" key="$2"
  grep -m1 "^\s*${key}:" "$file" 2>/dev/null \
    | sed 's/^[^:]*:\s*//' \
    | tr -d '"' \
    | tr -d "'" \
    | xargs
}

# ── Verify a single agent ────────────────────────────────────────────────

verify_agent() {
  local cfg="$1"
  local agent_id; agent_id="$(yaml_val "$cfg" "id")"
  local agent_dir; agent_dir="$(dirname "$cfg")"

  # Check E2EE is enabled
  local enc_enabled; enc_enabled="$(yaml_val "$cfg" "enabled")"
  # The first "enabled" is agent.enabled; we need encryption.enabled specifically
  enc_enabled="$(grep -A5 'encryption:' "$cfg" | grep -m1 'enabled:' | awk '{print $2}')"
  if [[ "$enc_enabled" != "true" ]]; then
    dim "  $agent_id — E2EE deshabilitado, saltando"
    return 0
  fi

  # Extract config values
  local user_id; user_id="$(yaml_val "$cfg" "user_id")"
  local username; username="$(echo "$user_id" | sed 's/@\([^:]*\):.*/\1/')"
  local token_env; token_env="$(yaml_val "$cfg" "access_token_env")"
  local pickle_env; pickle_env="$(yaml_val "$cfg" "pickle_key_env")"
  local recovery_env; recovery_env="$(yaml_val "$cfg" "recovery_key_env")"
  local store_path; store_path="$(grep -A5 'encryption:' "$cfg" | grep -m1 'store_path:' | sed 's/^[^:]*:\s*//' | tr -d '"' | xargs)"

  local token="${!token_env:-}"
  local pickle_key="${!pickle_env:-}"

  # Find password — convention: MATRIX_PASSWORD_<NORMALIZED>
  local norm; norm="$(echo "$username" | tr '-' '_' | tr '[:lower:]' '[:upper:]')"
  local pass_env="MATRIX_PASSWORD_${norm}"
  local password="${!pass_env:-}"

  # Validate required values
  if [[ -z "$token" ]]; then
    fail "  $agent_id — $token_env no está en .env"
    return 1
  fi
  if [[ -z "$password" ]]; then
    warn "  $agent_id — $pass_env no está en .env, intentando sin password..."
  fi

  info "$agent_id — verificando device..."
  dim "  user:       $username"
  dim "  store:      $store_path"
  dim "  pickle_env: $pickle_env"
  dim "  token_env:  $token_env"

  # Stop agent if running (crypto store can't be shared)
  local was_running=false
  if is_running "$agent_id"; then
    was_running=true
    info "  Deteniendo $agent_id antes de verificar..."
    "$REPO_ROOT/dev-scripts/server/stop.sh" "$agent_id"
    sleep 1
  fi

  # Build verify command
  local verify_bin="$REPO_ROOT/bin/verify"
  if [[ ! -x "$verify_bin" ]] || [[ "$(find ./cmd/verify -newer "$verify_bin" 2>/dev/null | head -1)" ]]; then
    info "  Compilando cmd/verify..."
    mkdir -p "$(dirname "$verify_bin")"
    "$GO" build -tags goolm -o "$verify_bin" ./cmd/verify || {
      fail "  No se pudo compilar cmd/verify"
      return 1
    }
  fi

  # Run verification
  local verify_args=(
    --homeserver "$MATRIX_HOMESERVER"
    --username "$username"
    --token "$token"
    --store "$store_path"
  )
  if [[ -n "$password" ]]; then
    verify_args+=(--password "$password")
  fi
  if [[ -n "$pickle_key" ]]; then
    verify_args+=(--pickle-key "$pickle_key")
  fi

  local output
  if output=$("$verify_bin" "${verify_args[@]}" 2>&1); then
    ok "$agent_id — verificación exitosa"

    # Extract recovery key from output if present
    local new_rk
    new_rk="$(echo "$output" | grep "^SSSS_RECOVERY_KEY_" | cut -d= -f2-)"
    if [[ -n "$new_rk" && -n "$recovery_env" ]]; then
      # Update .env with new recovery key (quoted — keys contain spaces)
      local quoted_rk="\"${new_rk}\""
      if grep -q "^${recovery_env}=" "$REPO_ROOT/.env"; then
        sed -i "s|^${recovery_env}=.*|${recovery_env}=${quoted_rk}|" "$REPO_ROOT/.env"
        ok "  Recovery key actualizada en .env ($recovery_env)"
      else
        echo "${recovery_env}=${quoted_rk}" >> "$REPO_ROOT/.env"
        ok "  Recovery key añadida a .env ($recovery_env)"
      fi
    fi
  else
    warn "$agent_id — verify output:"
    echo "$output"
    # If it says keys already exist, that's usually fine
    if echo "$output" | grep -q "signed with cross-signing key"; then
      ok "$agent_id — device firmado con keys existentes"
    else
      warn "$agent_id — puede necesitar atención manual"
    fi
  fi

  echo "$output" | sed 's/^/  /'

  # Restart agent if it was running
  if [[ "$was_running" == "true" ]]; then
    info "  Reiniciando $agent_id..."
    "$REPO_ROOT/dev-scripts/server/start.sh" "$agent_id"
  fi

  echo
}

# ── Main ──────────────────────────────────────────────────────────────────

echo
info "Verificación E2EE de agentes Matrix"
echo

if [[ -n "$TARGET" ]]; then
  cfg="$(config_path_for "$TARGET")"
  [[ -n "$cfg" ]] || fail "Agente '$TARGET' no encontrado"
  verify_agent "$cfg"
else
  while IFS='|' read -r id version enabled desc cfg; do
    [[ "$enabled" == "true" ]] || continue
    verify_agent "$cfg"
  done < <(list_agents_raw)
fi

ok "Verificación completada"
