#!/bin/bash

# Bakery-IA Local Registry Setup and Base Image Management
# Standardized script for setting up local registry and managing base images
# Usage: ./scripts/setup-local-registry.sh [start|stop|prepull|push|clean]

set -e

# Configuration
LOCAL_REGISTRY="localhost:5000"
REGISTRY_NAME="bakery-local-registry"
REGISTRY_DATA_DIR="$(pwd)/kind-registry"
DOCKER_USERNAME="uals"
DOCKER_PASSWORD="dckr_pat_zzEY5Q58x1S0puraIoKEtbpue3A"

# Standardized base images (optimized list)
BASE_IMAGES=(
    "python:3.11-slim"
    "postgres:17-alpine"
    "redis:7.4-alpine"
    "busybox:1.36"
    "busybox:latest"
    "curlimages/curl:latest"
    "bitnami/kubectl:latest"
    "alpine:3.18"
    "alpine:3.19"
    "gcr.io/kaniko-project/executor:v1.23.0"
    "alpine/git:2.43.0"
)

echo "=========================================="
echo "Bakery-IA Local Registry Manager"
echo "=========================================="
echo ""

# Function to authenticate with Docker Hub
authenticate_docker_hub() {
    echo "Authenticating with Docker Hub..."
    echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
    echo "✓ Authentication successful"
}

# Function to start local registry
start_registry() {
    echo "Starting local registry at $LOCAL_REGISTRY..."
    
    # Create data directory
    mkdir -p "$REGISTRY_DATA_DIR"
    
    # Check if registry is already running
    if docker ps -a --format '{{.Names}}' | grep -q "^$REGISTRY_NAME$"; then
        echo "Registry container already exists"
        if docker ps --format '{{.Names}}' | grep -q "^$REGISTRY_NAME$"; then
            echo "✓ Registry is already running"
            return 0
        else
            echo "Starting existing registry container..."
            docker start "$REGISTRY_NAME"
        fi
    else
        # Start new registry container
        docker run -d -p 5000:5000 --name "$REGISTRY_NAME" \
            -v "$REGISTRY_DATA_DIR:/var/lib/registry" \
            registry:2
    fi
    
    # Wait for registry to be ready
    echo "Waiting for registry to be ready..."
    for i in {1..30}; do
        if curl -s http://$LOCAL_REGISTRY/v2/ > /dev/null 2>&1; then
            echo "✓ Registry is ready"
            return 0
        fi
        sleep 1
    done
    
    echo "❌ Registry failed to start"
    exit 1
}

# Function to stop local registry
stop_registry() {
    echo "Stopping local registry..."
    docker stop "$REGISTRY_NAME" || true
    echo "✓ Registry stopped"
}

# Function to clean registry
clean_registry() {
    echo "Cleaning local registry..."
    stop_registry
    rm -rf "$REGISTRY_DATA_DIR"
    echo "✓ Registry cleaned"
}

# Function to pre-pull base images
prepull_images() {
    authenticate_docker_hub
    
    echo "Pre-pulling base images..."
    for image in "${BASE_IMAGES[@]}"; do
        echo "Pulling: $image"
        docker pull "$image"
        echo "  ✓ Successfully pulled $image"
    done
    
    echo "✓ All base images pre-pulled"
}

# Function to push images to local registry
push_images_to_registry() {
    echo "Pushing base images to local registry..."
    
    for image in "${BASE_IMAGES[@]}"; do
        local_image="$LOCAL_REGISTRY/$(echo $image | sed 's|/|_|g' | sed 's|:|_|g')"
        echo "Tagging and pushing: $image → $local_image"
        
        # Tag the image
        docker tag "$image" "$local_image"
        
        # Push to local registry
        docker push "$local_image"
        
        echo "  ✓ Pushed $local_image"
    done
    
    echo "✓ All base images pushed to local registry"
    
    # Show registry contents
    echo "Registry contents:"
    curl -s http://$LOCAL_REGISTRY/v2/_catalog | jq . || echo "Registry is running"
}

# Function to update Dockerfiles
update_dockerfiles() {
    echo "Updating Dockerfiles to use local registry..."
    
    # Update all Dockerfiles
    find services -name "Dockerfile" -exec sed -i '' \
        's|FROM python:3.11-slim|FROM localhost:5000/python_3.11-slim|g' {} +
    
    # Also update any remaining python references
    find services -name "Dockerfile" -exec sed -i '' \
        's|ghcr.io/library/python:3.11-slim|localhost:5000/python_3.11-slim|g' {} +
    
    echo "✓ Dockerfiles updated to use local registry"
}

# Function to revert Dockerfiles
revert_dockerfiles() {
    echo "Reverting Dockerfiles to use original images..."
    
    # Revert all Dockerfiles
    find services -name "Dockerfile" -exec sed -i '' \
        's|FROM localhost:5000/python_3.11-slim|FROM python:3.11-slim|g' {} +
    
    echo "✓ Dockerfiles reverted to original images"
}

# Function to show registry status
show_status() {
    echo "Local Registry Status:"
    echo "---------------------"
    
    if docker ps --format '{{.Names}}' | grep -q "^$REGISTRY_NAME$"; then
        echo "Status: Running"
        echo "Address: $LOCAL_REGISTRY"
        echo "Data Directory: $REGISTRY_DATA_DIR"
        
        echo ""
        echo "Images in registry:"
        curl -s http://$LOCAL_REGISTRY/v2/_catalog | jq -r '.repositories[]' || echo "Registry accessible"
    else
        echo "Status: Stopped"
        echo "To start: ./scripts/setup-local-registry.sh start"
    fi
}

# Function to show help
show_help() {
    echo "Usage: $0 [command]"
    echo ""
    echo "Commands:"
    echo "  start       Start local registry"
    echo "  stop        Stop local registry"
    echo "  prepull     Pre-pull base images from Docker Hub"
    echo "  push        Push pre-pulled images to local registry"
    echo "  update      Update Dockerfiles to use local registry"
    echo "  revert      Revert Dockerfiles to original images"
    echo "  clean       Clean registry (stop + remove data)"
    echo "  status      Show registry status"
    echo "  all         Run prepull + start + push + update"
    echo "  help        Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0 start prepull push update"
    echo "  $0 all"
    echo "  $0 clean"
}

# Main script logic
if [ $# -eq 0 ]; then
    show_help
    exit 1
fi

COMMAND="$1"
shift

case "$COMMAND" in
    start)
        start_registry
        ;;
    stop)
        stop_registry
        ;;
    prepull)
        prepull_images
        ;;
    push)
        push_images_to_registry
        ;;
    update)
        update_dockerfiles
        ;;
    revert)
        revert_dockerfiles
        ;;
    clean)
        clean_registry
        ;;
    status)
        show_status
        ;;
    all)
        authenticate_docker_hub
        start_registry
        prepull_images
        push_images_to_registry
        update_dockerfiles
        show_status
        ;;
    help|--help|-h)
        show_help
        ;;
    *)
        echo "Unknown command: $COMMAND"
        show_help
        exit 1
        ;;
esac

# Run additional commands if provided
for cmd in "$@"; do
    case "$cmd" in
        start)
            start_registry
            ;;
        stop)
            stop_registry
            ;;
        prepull)
            prepull_images
            ;;
        push)
            push_images_to_registry
            ;;
        update)
            update_dockerfiles
            ;;
        revert)
            revert_dockerfiles
            ;;
        clean)
            clean_registry
            ;;
        status)
            show_status
            ;;
        *)
            echo "Unknown command: $cmd"
            ;;
    esac
done

echo ""
echo "=========================================="
echo "Operation completed!"
echo "=========================================="