#!/usr/bin/env bash
set -euo pipefail

# thoughts-sync - Synchronize hardlinks in thoughts/searchable/
# Creates/updates hardlinks for all .md files in thoughts/ for efficient searching

THOUGHTS_DIR="thoughts"
SEARCHABLE_DIR="$THOUGHTS_DIR/searchable"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

info() {
  echo -e "${GREEN}[INFO]${NC} $1"
}

warn() {
  echo -e "${YELLOW}[WARN]${NC} $1"
}

error() {
  echo -e "${RED}[ERROR]${NC} $1"
  exit 1
}

debug() {
  if [ "${THOUGHTS_DEBUG:-0}" = "1" ]; then
    echo -e "${BLUE}[DEBUG]${NC} $1"
  fi
}

# Check if thoughts/ exists
if [ ! -d "$THOUGHTS_DIR" ]; then
  error "thoughts/ directory not found. Run 'thoughts-init' first."
fi

# Create searchable/ if it doesn't exist
mkdir -p "$SEARCHABLE_DIR"

# Track statistics
added=0
removed=0
skipped=0

info "Synchronizing thoughts/searchable/ hardlinks..."

# Temporarily disable exit-on-error for while loop (read returns non-zero when done)
set +e
# Find all .md files in thoughts/ (excluding searchable/ itself)
while IFS= read -r -d '' file; do
  # Get relative path from thoughts/ root
  rel_path="${file#"$THOUGHTS_DIR"/}"

  # Skip if already in searchable/
  if [[ "$rel_path" == searchable/* ]]; then
    continue
  fi

  # Target path in searchable/
  target="$SEARCHABLE_DIR/$rel_path"
  target_dir=$(dirname "$target")

  # Create target directory if needed
  mkdir -p "$target_dir"

  # Check if hardlink already exists and points to the same file
  if [ -e "$target" ]; then
    # Check if it's the same inode (already a hardlink)
    if [ "$file" -ef "$target" ]; then
      debug "Skipping $rel_path (already linked)"
      ((skipped++))
      continue
    else
      # Different file, remove old link
      debug "Removing old link: $rel_path"
      rm -f "$target"
      ((removed++))
    fi
  fi

  # Create hardlink (try hardlink first, fallback to symlink if cross-filesystem)
  if ln "$file" "$target" 2>/dev/null; then
    debug "Hardlinked: $rel_path"
    ((added++))
  else
    # Fallback to symlink if hardlink fails (e.g., cross-filesystem)
    warn "Could not create hardlink for $rel_path (cross-filesystem?), using symlink"
    # Create relative symlink
    # Try realpath first (GNU coreutils), then python fallback, then simple relative path
    if rel_source=$(realpath --relative-to="$target_dir" "$file" 2>/dev/null); then
      :  # Success, use $rel_source
    elif rel_source=$(python3 -c "import os.path; print(os.path.relpath('$file', '$target_dir'))" 2>/dev/null); then
      :  # Success, use $rel_source
    else
      # Fallback: construct simple relative path
      rel_source="../../$rel_path"
    fi
    ln -sf "$rel_source" "$target"
    ((added++))
  fi
done < <(find "$THOUGHTS_DIR" -type f -name "*.md" -print0 2>/dev/null || true)
# Re-enable exit-on-error
set -e

# Clean up orphaned links in searchable/
info "Cleaning up orphaned links..."
orphaned=0
# Temporarily disable exit-on-error for while loop
set +e
while IFS= read -r -d '' link; do
  # Get relative path from searchable/
  rel_path="${link#"$SEARCHABLE_DIR"/}"
  source_file="$THOUGHTS_DIR/$rel_path"

  # Check if source file still exists
  if [ ! -f "$source_file" ]; then
    debug "Removing orphaned link: $rel_path"
    rm -f "$link"
    ((orphaned++))
  fi
done < <(find "$SEARCHABLE_DIR" -type f -name "*.md" -print0 2>/dev/null || true)
# Re-enable exit-on-error
set -e

# Remove empty directories in searchable/
find "$SEARCHABLE_DIR" -type d -empty -delete 2>/dev/null || true

# Summary
echo ""
info "✓ Sync complete!"
echo "  Links added: $added"
echo "  Links removed: $removed"
echo "  Links skipped: $skipped"
echo "  Orphaned links cleaned: $orphaned"

# Count total files
total=$(find "$SEARCHABLE_DIR" -type f -name "*.md" | wc -l | tr -d ' ')
echo "  Total .md files in searchable/: $total"

if [ "$total" -eq 0 ]; then
  warn "No .md files found. Add some documents to thoughts/ first."
fi
