#!/bin/bash

# ProofMode Docker Example Script
# This script demonstrates various ways to use ProofMode with Docker

set -e

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

# Configuration
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
INPUT_DIR="${SCRIPT_DIR}/input"
OUTPUT_DIR="${SCRIPT_DIR}/output"
TEST_IMAGE="${INPUT_DIR}/test.jpg"

# Docker image name (can be overridden) - use local build by default
DOCKER_IMAGE="${PROOFMODE_IMAGE:-proofmode-rust:local}"

# Functions
print_header() {
    echo -e "\n${BLUE}=== $1 ===${NC}"
}

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

print_info() {
    echo -e "${YELLOW}ℹ $1${NC}"
}

setup_directories() {
    print_header "Setting up directories"
    
    mkdir -p "$INPUT_DIR" "$OUTPUT_DIR"
    print_success "Created input and output directories"
    
    # Create a test image if it doesn't exist
    if [ ! -f "$TEST_IMAGE" ]; then
        print_info "Creating test image..."
        # Use ImageMagick if available, otherwise create with base64
        if command -v convert &> /dev/null; then
            convert -size 640x480 xc:blue -pointsize 48 -fill white \
                -gravity center -annotate +0+0 "ProofMode Test Image" \
                "$TEST_IMAGE"
        else
            # Create a minimal valid JPEG using base64
            echo "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAABAAEDAREAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAX/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCwAAH/2Q==" | base64 -d > "$TEST_IMAGE"
        fi
        print_success "Created test image: $TEST_IMAGE"
    fi
}

# Example 1: Generate proof using Docker run
example_docker_run() {
    print_header "Example 1: Generate proof with docker run"
    
    docker run --rm \
        --user $(id -u):$(id -g) \
        -v "$INPUT_DIR:/app/input:ro" \
        -v "$OUTPUT_DIR:/app/output" \
        "$DOCKER_IMAGE" \
        generate -f /app/input/test.jpg -s /app/output
    
    if find "$OUTPUT_DIR" -name "*.proof.json" | grep -q .; then
        print_success "Proof generated successfully"
        print_info "Proof files:"
        find "$OUTPUT_DIR" -name "*.proof.*" -exec ls -la {} \;
    else
        print_error "Failed to generate proof"
    fi
}

# Example 2: Check proof
example_check_proof() {
    print_header "Example 2: Check proof with docker run"
    
    # First, ensure we have a proof to check
    local proof_file=$(find "$OUTPUT_DIR" -name "*.proof.json" | head -n1)
    
    if [ -z "$proof_file" ]; then
        print_error "No proof file found. Run example 1 first."
        return 1
    fi
    
    docker run --rm \
        --user $(id -u):$(id -g) \
        -v "$OUTPUT_DIR:/app/proofs:ro" \
        -v "$INPUT_DIR:/app/input:ro" \
        "$DOCKER_IMAGE" \
        check -f "/app/proofs/$(basename "$proof_file")"
    
    print_success "Proof verification completed"
}

# Example 3: Batch processing
example_batch_processing() {
    print_header "Example 3: Batch processing multiple files"
    
    # Create additional test images
    for i in {1..3}; do
        cp "$TEST_IMAGE" "$INPUT_DIR/test_$i.jpg" 2>/dev/null || true
    done
    
    # Process all images
    docker run --rm \
        --user $(id -u):$(id -g) \
        -v "$INPUT_DIR:/app/input:ro" \
        -v "$OUTPUT_DIR:/app/output" \
        "$DOCKER_IMAGE" \
        generate -d /app/input -s /app/output
    
    print_success "Batch processing completed"
    print_info "Generated proofs:"
    find "$OUTPUT_DIR" -name "*.proof.json" | wc -l
}

# Example 4: Using Docker Compose
example_docker_compose() {
    print_header "Example 4: Using Docker Compose"
    
    # Create a simple compose override for testing
    cat > "${SCRIPT_DIR}/docker-compose.override.yml" << EOF
version: '3.8'

services:
  proofmode:
    image: $DOCKER_IMAGE
    command: generate -f /app/input/test.jpg -s /app/output
EOF
    
    cd "$SCRIPT_DIR"
    docker-compose up --no-deps proofmode
    
    print_success "Docker Compose example completed"
}

# Example 5: Interactive mode
example_interactive() {
    print_header "Example 5: Interactive ProofMode session"
    
    print_info "Starting interactive container..."
    print_info "Try commands like:"
    print_info "  proofmode generate -f /app/input/test.jpg -s /app/output --storage /output"
    print_info "  proofmode check -f /output/<hash>.proof.json"
    print_info "  proofmode --help"
    print_info "Type 'exit' to quit"
    
    docker run --rm -it \
        --user $(id -u):$(id -g) \
        -v "$INPUT_DIR:/app/input:ro" \
        -v "$OUTPUT_DIR:/app/output" \
        --entrypoint /bin/sh \
        "$DOCKER_IMAGE"
}

# Example 6: Generate with custom parameters
example_custom_params() {
    print_header "Example 6: Using custom parameters"
    
    # ProofMode accepts email and passphrase parameters
    docker run --rm \
        --user $(id -u):$(id -g) \
        -v "$INPUT_DIR:/app/input:ro" \
        -v "$OUTPUT_DIR:/app/output" \
        "$DOCKER_IMAGE" \
        generate -f /app/input/test.jpg -s /app/output \
        -e "user@example.com" \
        -p "secure-passphrase"
    
    print_success "Generated proof with custom parameters"
}

# Example 7: Network volume for sharing
example_network_volume() {
    print_header "Example 7: Using Docker volumes for persistence"
    
    # Create a named volume
    docker volume create proofmode-data || true
    
    # Generate proof using volume
    docker run --rm \
        --user $(id -u):$(id -g) \
        -v "$INPUT_DIR:/app/input:ro" \
        -v proofmode-data:/app/output \
        "$DOCKER_IMAGE" \
        generate -f /app/input/test.jpg -s /app/output
    
    # List files in volume
    docker run --rm \
        -v proofmode-data:/data \
        alpine ls -la /data/
    
    print_success "Proof stored in Docker volume 'proofmode-data'"
}

# Clean up function
cleanup() {
    print_header "Cleaning up"
    
    if [ "$1" == "all" ]; then
        rm -rf "$OUTPUT_DIR"/*
        rm -f "$INPUT_DIR"/test_*.jpg
        rm -f "${SCRIPT_DIR}/docker-compose.override.yml"
        rm -f "${SCRIPT_DIR}/config.toml"
        docker volume rm proofmode-data 2>/dev/null || true
        print_success "All example files cleaned up"
    else
        print_info "Run '$0 cleanup all' to remove all generated files"
    fi
}

# Main menu
show_menu() {
    echo -e "\n${BLUE}ProofMode Docker Examples${NC}"
    echo "========================="
    echo "1) Generate proof (docker run)"
    echo "2) Check proof"
    echo "3) Batch processing"
    echo "4) Docker Compose example"
    echo "5) Interactive mode"
    echo "6) Custom parameters"
    echo "7) Docker volumes"
    echo "8) Run all examples"
    echo "9) Cleanup"
    echo "0) Exit"
}

# Run all examples
run_all() {
    setup_directories
    example_docker_run
    example_check_proof
    example_batch_processing
    example_custom_params
    example_network_volume
    print_success "All examples completed!"
}

# Main script
main() {
    # Check if Docker is installed
    if ! command -v docker &> /dev/null; then
        print_error "Docker is not installed. Please install Docker first."
        exit 1
    fi
    
    # Handle command line arguments
    case "$1" in
        "cleanup")
            cleanup "$2"
            exit 0
            ;;
        "all")
            setup_directories
            run_all
            exit 0
            ;;
        "")
            # Interactive menu
            ;;
        *)
            print_error "Unknown command: $1"
            echo "Usage: $0 [all|cleanup]"
            exit 1
            ;;
    esac
    
    # Interactive menu loop
    while true; do
        show_menu
        read -p "Select an option: " choice
        
        case $choice in
            1) setup_directories && example_docker_run ;;
            2) setup_directories && example_check_proof ;;
            3) setup_directories && example_batch_processing ;;
            4) setup_directories && example_docker_compose ;;
            5) setup_directories && example_interactive ;;
            6) setup_directories && example_custom_params ;;
            7) setup_directories && example_network_volume ;;
            8) run_all ;;
            9) cleanup ;;
            0) echo "Goodbye!"; exit 0 ;;
            *) print_error "Invalid option" ;;
        esac
        
        echo
        read -p "Press Enter to continue..."
    done
}

# Run main function
main "$@"