#!/bin/bash
###############################################################################
# migration-restore.sh
#
# Restores a ClaudeTools environment from an encrypted migration archive.
# Works in Git Bash on Windows AND native Linux bash.
#
# Usage: ./migration-restore.sh <archive.tar.gpg> [target_dir]
#   archive.tar.gpg  Path to the encrypted migration archive
#   target_dir       Where to clone/restore (default: $HOME/ClaudeTools)
###############################################################################

set -euo pipefail

# ---------------------------------------------------------------------------
# Globals
# ---------------------------------------------------------------------------
ARCHIVE_PATH="${1:-}"
TARGET_DIR="${2:-"${HOME}/ClaudeTools"}"
GITEA_REPO="https://git.azcomputerguru.com/azcomputerguru/claudetools.git"
TEMP_EXTRACT=""
WARN_COUNT=0

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
log_info()    { echo "[INFO]    $*"; }
log_ok()      { echo "[OK]      $*"; }
log_warn()    { echo "[WARNING] $*"; WARN_COUNT=$((WARN_COUNT + 1)); }
log_error()   { echo "[ERROR]   $*"; }

cleanup() {
    if [[ -n "$TEMP_EXTRACT" && -d "$TEMP_EXTRACT" ]]; then
        log_info "Cleaning up temporary extraction directory..."
        rm -rf "$TEMP_EXTRACT"
    fi
}
trap cleanup EXIT

check_tool() {
    local tool="$1"
    if ! command -v "$tool" &>/dev/null; then
        log_error "Required tool not found: ${tool}"
        log_error "Please install ${tool} before running this script."
        exit 1
    fi
    log_ok "Found: ${tool}"
}

# Derive the Claude projects directory name from the target path.
# On Windows (Git Bash): /d/ClaudeTools -> D--ClaudeTools
# On Linux: /home/user/ClaudeTools -> -home-user-ClaudeTools
derive_claude_project_name() {
    local abs_target
    abs_target="$(cd "$TARGET_DIR" && pwd)"

    # Check if we are on Windows (Git Bash) by looking at path format
    if [[ "$abs_target" =~ ^/([a-zA-Z])/(.*) ]]; then
        # Git Bash path: /d/ClaudeTools -> D--ClaudeTools
        local drive="${BASH_REMATCH[1]^^}"
        local rest="${BASH_REMATCH[2]}"
        echo "${drive}--${rest//\//-}"
    elif [[ "$abs_target" =~ ^([a-zA-Z]):(.*) ]]; then
        # Raw Windows path: D:\ClaudeTools -> D--ClaudeTools
        local drive="${BASH_REMATCH[1]^^}"
        local rest="${BASH_REMATCH[2]}"
        rest="${rest//\\/-}"
        rest="${rest//\//-}"
        rest="${rest#-}"
        echo "${drive}--${rest}"
    else
        # Linux/macOS: /home/user/ClaudeTools -> -home-user-ClaudeTools
        local name="${abs_target//\//-}"
        name="${name#-}"
        echo "${name}"
    fi
}

# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
    echo "============================================================"
    echo " ClaudeTools Migration Restore"
    echo " $(date '+%Y-%m-%d %H:%M:%S')"
    echo "============================================================"
    echo ""

    # ------------------------------------------------------------------
    # Validate arguments
    # ------------------------------------------------------------------
    if [[ -z "$ARCHIVE_PATH" ]]; then
        log_error "Usage: $0 <archive.tar.gpg> [target_dir]"
        log_error "  archive.tar.gpg  Encrypted migration archive"
        log_error "  target_dir       Restore location (default: \$HOME/ClaudeTools)"
        exit 1
    fi

    if [[ ! -f "$ARCHIVE_PATH" ]]; then
        log_error "Archive not found: ${ARCHIVE_PATH}"
        exit 1
    fi

    log_info "Archive:    ${ARCHIVE_PATH}"
    log_info "Target dir: ${TARGET_DIR}"
    echo ""

    # ------------------------------------------------------------------
    # Check required tools
    # ------------------------------------------------------------------
    log_info "--- Checking required tools ---"
    check_tool git
    check_tool gpg
    check_tool tar
    echo ""

    # ------------------------------------------------------------------
    # Decrypt archive
    # ------------------------------------------------------------------
    log_info "--- Decrypting archive ---"
    log_info "You will be prompted for the passphrase."
    echo ""

    TEMP_EXTRACT="$(mktemp -d 2>/dev/null || mktemp -d -t 'migration-restore')"
    local tar_tmp="${TEMP_EXTRACT}/archive.tar"

    if [[ -n "${GPG_PASSPHRASE:-}" ]]; then
        echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 \
            --decrypt --output "$tar_tmp" "$ARCHIVE_PATH"
    else
        gpg --decrypt --output "$tar_tmp" "$ARCHIVE_PATH"
    fi

    if [[ ! -f "$tar_tmp" ]]; then
        log_error "Decryption failed. Check your passphrase and try again."
        exit 1
    fi
    log_ok "Archive decrypted."
    echo ""

    # ------------------------------------------------------------------
    # Extract archive to temp location
    # ------------------------------------------------------------------
    log_info "--- Extracting archive ---"
    local extract_dir="${TEMP_EXTRACT}/contents"
    mkdir -p "$extract_dir"
    tar -xf "$tar_tmp" -C "$extract_dir"
    rm -f "$tar_tmp"
    log_ok "Archive extracted."

    # Show manifest if present
    if [[ -f "${extract_dir}/MIGRATION_MANIFEST.txt" ]]; then
        echo ""
        log_info "--- Migration Manifest ---"
        cat "${extract_dir}/MIGRATION_MANIFEST.txt"
        echo ""
    fi

    # ------------------------------------------------------------------
    # Clone repository
    # ------------------------------------------------------------------
    log_info "--- Cloning repository ---"

    if [[ -d "$TARGET_DIR/.git" ]]; then
        log_warn "Target directory already contains a git repo: ${TARGET_DIR}"
        log_info "Skipping clone; will overlay migration files into existing repo."
    elif [[ -d "$TARGET_DIR" ]]; then
        # Directory exists but is not a git repo
        log_warn "Target directory exists but is not a git repo: ${TARGET_DIR}"
        log_info "Attempting clone into existing directory..."
        git clone "$GITEA_REPO" "${TARGET_DIR}.tmp"
        # Move .git and tracked files into existing directory
        mv "${TARGET_DIR}.tmp/.git" "${TARGET_DIR}/"
        # Checkout working tree into existing directory
        (cd "$TARGET_DIR" && git checkout -- .)
        rm -rf "${TARGET_DIR}.tmp"
        log_ok "Cloned repository into existing directory."
    else
        git clone "$GITEA_REPO" "$TARGET_DIR"
        log_ok "Cloned repository to: ${TARGET_DIR}"
    fi
    echo ""

    # ------------------------------------------------------------------
    # Overlay non-git files from migration archive
    # ------------------------------------------------------------------
    log_info "--- Restoring non-git files ---"

    # Copy everything except claude-context (handled separately) and manifest
    local item
    for item in "$extract_dir"/*; do
        local basename
        basename="$(basename "$item")"

        # Skip claude-context dir and manifest
        if [[ "$basename" == "claude-context" || "$basename" == "MIGRATION_MANIFEST.txt" ]]; then
            continue
        fi

        if [[ -d "$item" ]]; then
            cp -a "$item" "$TARGET_DIR/"
            log_ok "Restored directory: ${basename}"
        elif [[ -f "$item" ]]; then
            cp -a "$item" "$TARGET_DIR/"
            log_ok "Restored file: ${basename}"
        fi
    done

    # Handle dotfiles (hidden files/dirs from archive root)
    for item in "$extract_dir"/.*; do
        local basename
        basename="$(basename "$item")"
        [[ "$basename" == "." || "$basename" == ".." ]] && continue

        if [[ -d "$item" ]]; then
            # Merge directory contents (e.g., .claude/)
            cp -a "$item"/. "$TARGET_DIR/${basename}/" 2>/dev/null || cp -a "$item" "$TARGET_DIR/"
            log_ok "Restored directory: ${basename}"
        elif [[ -f "$item" ]]; then
            cp -a "$item" "$TARGET_DIR/"
            log_ok "Restored file: ${basename}"
        fi
    done
    echo ""

    # ------------------------------------------------------------------
    # Restore Claude AI context
    # ------------------------------------------------------------------
    log_info "--- Restoring Claude AI context ---"

    local claude_ctx_src="${extract_dir}/claude-context"
    if [[ -d "$claude_ctx_src" ]]; then
        local project_name
        project_name="$(derive_claude_project_name)"
        local claude_ctx_dst="${HOME}/.claude/projects/${project_name}"

        mkdir -p "$claude_ctx_dst"
        cp -a "$claude_ctx_src"/. "$claude_ctx_dst/"
        log_ok "Restored Claude context to: ${claude_ctx_dst}"
    else
        log_warn "No claude-context directory found in archive. Skipping."
    fi
    echo ""

    # ------------------------------------------------------------------
    # Initialize submodules
    # ------------------------------------------------------------------
    log_info "--- Initializing git submodules ---"
    (cd "$TARGET_DIR" && git submodule update --init --recursive) && \
        log_ok "Submodules initialized." || \
        log_warn "Submodule initialization had issues. You may need to run it manually."
    echo ""

    # ------------------------------------------------------------------
    # Summary and post-restore checklist
    # ------------------------------------------------------------------
    echo "============================================================"
    echo " Restore Complete"
    echo "============================================================"
    echo ""
    echo "  Target:   ${TARGET_DIR}"
    echo "  Warnings: ${WARN_COUNT}"
    echo ""
    echo "============================================================"
    echo " Post-Restore Checklist"
    echo "============================================================"
    echo ""
    echo "  [ ] Verify credentials.md contains correct, unredacted values"
    echo "      File: ${TARGET_DIR}/credentials.md"
    echo ""
    echo "  [ ] Set up Python virtual environment for MCP servers"
    echo "      cd ${TARGET_DIR} && python -m venv .venv"
    echo "      source .venv/bin/activate  (or .venv\\Scripts\\activate on Windows)"
    echo "      pip install -r requirements.txt"
    echo ""
    echo "  [ ] Configure Claude Code CLI"
    echo "      Run: claude  (first launch will prompt for authentication)"
    echo "      Verify .claude/ context was restored correctly"
    echo ""
    echo "  [ ] Test Gitea SSH access"
    echo "      Run: ssh -p 2222 git@172.16.3.20"
    echo "      If it fails, copy your SSH keys and update ~/.ssh/config"
    echo ""
    echo "  [ ] Rebuild grepai index"
    echo "      The semantic search index is machine-specific."
    echo "      Run grepai indexing from within Claude Code."
    echo ""
    echo "  [ ] Verify .env and .mcp.json values are correct for new machine"
    echo ""
    echo "  [ ] Test database connectivity"
    echo "      Ensure 172.16.3.30:3306 is reachable from this machine"
    echo ""
    log_ok "Done."
}

main "$@"
