#!/bin/bash
# Claude Code Agents Sync Script
# Syncs local agents with GitHub repository and backs up to Gitea

set -euo pipefail

# Configuration
AGENTS_DIR="${HOME}/.claude/agents"
BACKUP_DIR="${AGENTS_DIR}.backup.$(date +%Y%m%d-%H%M%S)"
GITHUB_REPO="https://github.com/contains-studio/agents"
TEMP_DIR="/tmp/claude-agents-sync-$RANDOM"
UPSTREAM_DIR="$TEMP_DIR/upstream"
LOG_FILE="${AGENTS_DIR}/update.log"

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

# Logging function
log() {
    local level=$1
    shift
    local message="$@"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}

# Print colored message
print_msg() {
    local color=$1
    shift
    echo -e "${color}$*${NC}"
}

# Create backup
create_backup() {
    print_msg "$BLUE" "📦 Creating backup..."
    if cp -r "$AGENTS_DIR" "$BACKUP_DIR"; then
        print_msg "$GREEN" "✓ Backup created: $BACKUP_DIR"
        log "INFO" "Backup created at $BACKUP_DIR"
    else
        print_msg "$RED" "✗ Failed to create backup"
        log "ERROR" "Backup creation failed"
        exit 1
    fi
}

# Download upstream agents
download_upstream() {
    print_msg "$BLUE" "📥 Downloading agents from $GITHUB_REPO..."
    mkdir -p "$TEMP_DIR"

    if command -v git &> /dev/null; then
        # Use git if available (faster)
        git clone --depth 1 "$GITHUB_REPO" "$UPSTREAM_DIR" 2>/dev/null || {
            print_msg "$RED" "✗ Failed to clone repository"
            log "ERROR" "Git clone failed"
            exit 1
        }
    else
        # Fallback to wget/curl
        print_msg "$YELLOW" "⚠ Git not found, downloading archive..."
        local archive="$TEMP_DIR/agents.tar.gz"
        if command -v wget &> /dev/null; then
            wget -q "$GITHUB_REPO/archive/main.tar.gz" -O "$archive"
        elif command -v curl &> /dev/null; then
            curl -sL "$GITHUB_REPO/archive/main.tar.gz" -o "$archive"
        else
            print_msg "$RED" "✗ Need git, wget, or curl"
            exit 1
        fi
        mkdir -p "$UPSTREAM_DIR"
        tar -xzf "$archive" -C "$UPSTREAM_DIR" --strip-components=1
    fi

    print_msg "$GREEN" "✓ Downloaded upstream agents"
    log "INFO" "Downloaded agents from $GITHUB_REPO"
}

# Compare and sync agents
sync_agents() {
    print_msg "$BLUE" "🔄 Syncing agents..."

    local new_agents=()
    local updated_agents=()
    local custom_agents=()

    # Find all agent files in upstream
    while IFS= read -r upstream_file; do
        local rel_path="${upstream_file#$UPSTREAM_DIR/}"
        local local_file="$AGENTS_DIR/$rel_path"

        if [[ ! -f "$local_file" ]]; then
            # New agent
            new_agents+=("$rel_path")
            mkdir -p "$(dirname "$local_file")"
            cp "$upstream_file" "$local_file"
            log "INFO" "Added new agent: $rel_path"
        elif ! diff -q "$upstream_file" "$local_file" &>/dev/null; then
            # Updated agent - check if customized
            if grep -q "CUSTOMIZED" "$local_file" 2>/dev/null || \
               [[ -f "${local_file}.local" ]]; then
                custom_agents+=("$rel_path")
                log "WARN" "Skipped customized agent: $rel_path"
            else
                updated_agents+=("$rel_path")
                cp "$upstream_file" "$local_file"
                log "INFO" "Updated agent: $rel_path"
            fi
        fi
    done < <(find "$UPSTREAM_DIR" -name "*.md" -type f)

    # Report results
    echo ""
    print_msg "$GREEN" "✨ New agents (${#new_agents[@]}):"
    for agent in "${new_agents[@]}"; do
        echo "  + $agent"
    done | head -20

    echo ""
    print_msg "$YELLOW" "📝 Updated agents (${#updated_agents[@]}):"
    for agent in "${updated_agents[@]}"; do
        echo "  ~ $agent"
    done | head -20

    if [[ ${#custom_agents[@]} -gt 0 ]]; then
        echo ""
        print_msg "$YELLOW" "⚠️  Preserved custom agents (${#custom_agents[@]}):"
        for agent in "${custom_agents[@]}"; do
            echo "  • $agent"
        done | head -20
    fi

    # Summary
    local total_changes=$((${#new_agents[@]} + ${#updated_agents[@]}))
    log "INFO" "Sync complete: ${#new_agents[@]} new, ${#updated_agents[@]} updated, ${#custom_agents[@]} preserved"
}

# Commit to git
commit_to_git() {
    print_msg "$BLUE" "💾 Committing to git..."

    cd "$AGENTS_DIR"

    # Check if there are changes
    if git diff --quiet && git diff --cached --quiet; then
        print_msg "$YELLOW" "⚠️  No changes to commit"
        return
    fi

    # Add all agents
    git add . -- '*.md'

    # Commit with descriptive message
    local commit_msg="Update agents from upstream

$(date '+%Y-%m-%d %H:%M:%S')

Changes:
- $(git diff --cached --name-only | wc -l) files updated
- From: $GITHUB_REPO"

    git commit -m "$commit_msg" 2>/dev/null || {
        print_msg "$YELLOW" "⚠️  Nothing to commit or git not configured"
        log "WARN" "Git commit skipped"
        return
    }

    print_msg "$GREEN" "✓ Committed to local git"
    log "INFO" "Committed changes to git"
}

# Push to Gitea
push_to_gitea() {
    if [[ -z "${GITEA_REPO_URL:-}" ]]; then
        print_msg "$YELLOW" "⚠️  GITEA_REPO_URL not set, skipping push"
        print_msg "$YELLOW" "   Set it with: export GITEA_REPO_URL='your-gitea-repo-url'"
        log "WARN" "GITEA_REPO_URL not set, push skipped"
        return
    fi

    print_msg "$BLUE" "📤 Pushing to Gitea..."

    cd "$AGENTS_DIR"

    # Ensure remote exists
    if ! git remote get-url origin &>/dev/null; then
        git remote add origin "$GITEA_REPO_URL"
    fi

    if git push -u origin main 2>/dev/null || git push -u origin master 2>/dev/null; then
        print_msg "$GREEN" "✓ Pushed to Gitea"
        log "INFO" "Pushed to Gitea: $GITEA_REPO_URL"
    else
        print_msg "$YELLOW" "⚠️  Push failed (check credentials/URL)"
        log "ERROR" "Push to Gitea failed"
    fi
}

# Cleanup
cleanup() {
    rm -rf "$TEMP_DIR"
}

# Rollback function
rollback() {
    print_msg "$RED" "🔄 Rolling back to backup..."
    if [[ -d "$BACKUP_DIR" ]]; then
        rm -rf "$AGENTS_DIR"
        mv "$BACKUP_DIR" "$AGENTS_DIR"
        print_msg "$GREEN" "✓ Rolled back successfully"
        log "INFO" "Rolled back to $BACKUP_DIR"
    else
        print_msg "$RED" "✗ No backup found!"
        log "ERROR" "Rollback failed - no backup"
    fi
}

# Main execution
main() {
    print_msg "$BLUE" "🚀 Claude Code Agents Sync"
    print_msg "$BLUE" "════════════════════════════"
    echo ""

    trap cleanup EXIT
    trap rollback ERR

    create_backup
    download_upstream
    sync_agents
    commit_to_git
    push_to_gitea

    echo ""
    print_msg "$GREEN" "✅ Sync complete!"
    print_msg "$BLUE" "💾 Backup: $BACKUP_DIR"
    print_msg "$BLUE" "📋 Log: $LOG_FILE"
    echo ""
    print_msg "$YELLOW" "To rollback: rm -rf $AGENTS_DIR && mv $BACKUP_DIR $AGENTS_DIR"
}

# Run main function
main "$@"
