#!/bin/bash
# Find all KeePassXC database files (.kdbx) on the system and move them to a single location
# Uses 'fd' for fast searching - install with: sudo pacman -S fd
#
# Usage: ./find_keepassxc.sh [destination_directory]
# Default destination: ~/Keepass

set -euo pipefail

# Source common library if available
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
if [[ -f "$SCRIPT_DIR/../lib/common.sh" ]]; then
  # shellcheck source=../lib/common.sh
  source "$SCRIPT_DIR/../lib/common.sh"
else
  log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"; }
fi

# Configuration
DEST_DIR="${1:-$HOME/Keepass}"
SEARCH_ROOT="/"
TIMEOUT_SECONDS=30

# Ensure fd is installed
if ! command -v fd &> /dev/null; then
  log "ERROR: 'fd' is not installed. Install with: sudo pacman -S fd"
  exit 1
fi

# Create destination directory if it doesn't exist
mkdir -p "$DEST_DIR"
log "Destination directory: $DEST_DIR"

# Find all .kdbx files using fd (very fast, respects .gitignore by default, but we use -u for unrestricted)
# -e kdbx: search by extension
# -u: unrestricted (include hidden and ignored files)
# -a: absolute paths
# --one-file-system: don't cross filesystem boundaries (optional, remove if you want to search mounted drives)
log "Searching for .kdbx files across the system (timeout: ${TIMEOUT_SECONDS}s)..."

# Use timeout to ensure the search doesn't take too long
# Exclude /proc, /sys, /dev, /run, /tmp, /var/cache, /var/tmp for speed
FOUND_FILES=$(timeout "$TIMEOUT_SECONDS" fd \
  -e kdbx \
  -u \
  -a \
  --exclude '/proc' \
  --exclude '/sys' \
  --exclude '/dev' \
  --exclude '/run' \
  --exclude '/tmp' \
  --exclude '/var/cache' \
  --exclude '/var/tmp' \
  --exclude '/snap' \
  --exclude '/.snapshots' \
  --exclude '/lost+found' \
  . "$SEARCH_ROOT" 2> /dev/null || true)

if [[ -z $FOUND_FILES ]]; then
  log "No .kdbx files found."
  exit 0
fi

# Count and display found files
FILE_COUNT=$(echo "$FOUND_FILES" | wc -l)
log "Found $FILE_COUNT .kdbx file(s):"
echo "$FOUND_FILES" | while read -r file; do
  echo "  - $file"
done

# Move files to destination
log "Moving files to $DEST_DIR..."
MOVED_COUNT=0
SKIPPED_COUNT=0

while IFS= read -r src_file; do
  [[ -z $src_file ]] && continue

  # Skip if file is already in destination
  if [[ "$(dirname "$src_file")" == "$DEST_DIR" ]]; then
    log "Skipping (already in destination): $src_file"
    ((SKIPPED_COUNT++)) || true
    continue
  fi

  # Get the base filename
  base_name=$(basename "$src_file")
  dest_file="$DEST_DIR/$base_name"

  # Handle filename conflicts by adding a number suffix
  if [[ -f $dest_file ]]; then
    # Check if it's the exact same file (by content)
    if cmp -s "$src_file" "$dest_file"; then
      log "Skipping (identical file exists): $src_file"
      # Remove the duplicate source file
      rm -v "$src_file"
      ((SKIPPED_COUNT++)) || true
      continue
    fi

    # Different file with same name - add suffix
    counter=1
    name_without_ext="${base_name%.kdbx}"
    while [[ -f $dest_file ]]; do
      dest_file="$DEST_DIR/${name_without_ext} ($counter).kdbx"
      ((counter++))
    done
    log "Renaming to avoid conflict: $base_name -> $(basename "$dest_file")"
  fi

  # Move the file
  if mv -v "$src_file" "$dest_file"; then
    ((MOVED_COUNT++)) || true
  else
    log "ERROR: Failed to move $src_file"
  fi
done <<< "$FOUND_FILES"

log "Done! Moved $MOVED_COUNT file(s), skipped $SKIPPED_COUNT file(s)."
log "All KeePassXC databases are now in: $DEST_DIR"

# List final contents
log "Contents of $DEST_DIR:"
ls -la "$DEST_DIR"/*.kdbx 2> /dev/null || log "No .kdbx files in destination"
