#!/bin/bash

# TankStopp Docker Build Script
# This script builds Docker images for the TankStopp application

set -e  # Exit on any error

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

# Default values
IMAGE_NAME="tankstopp"
TAG="latest"
DOCKERFILE="Dockerfile"
CONTEXT="."
BUILD_ARGS=""
PLATFORM=""
PUSH=false
NO_CACHE=false
QUIET=false
ENVIRONMENT="production"

# Functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

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

show_help() {
    cat << EOF
TankStopp Docker Build Script

Usage: $0 [OPTIONS]

OPTIONS:
    -h, --help              Show this help message
    -t, --tag TAG          Image tag (default: latest)
    -e, --env ENV          Environment: development|production (default: production)
    -f, --file FILE        Dockerfile path (default: Dockerfile)
    -c, --context PATH     Build context path (default: .)
    -p, --platform ARCH    Target platform (e.g., linux/amd64,linux/arm64)
    --push                 Push image to registry after build
    --no-cache             Build without using cache
    --quiet                Suppress build output
    --build-arg ARG=VALUE  Pass build arguments
    --clean                Clean up old images before building

EXAMPLES:
    # Build production image
    $0 --tag v1.0.0 --env production

    # Build development image
    $0 --tag dev --env development

    # Build multi-platform image
    $0 --tag latest --platform linux/amd64,linux/arm64

    # Build and push to registry
    $0 --tag v1.0.0 --push

    # Build with custom build args
    $0 --build-arg VERSION=1.0.0 --build-arg BUILD_DATE=\$(date -u +'%Y-%m-%dT%H:%M:%SZ')

ENVIRONMENT CONFIGURATIONS:
    production    - Optimized for production deployment
    development   - Includes development tools and debugging

EOF
}

check_requirements() {
    log_info "Checking requirements..."

    if ! command -v docker &> /dev/null; then
        log_error "Docker is not installed or not in PATH"
        exit 1
    fi

    if ! docker info &> /dev/null; then
        log_error "Docker daemon is not running"
        exit 1
    fi

    if [ ! -f "$DOCKERFILE" ]; then
        log_error "Dockerfile not found: $DOCKERFILE"
        exit 1
    fi

    if [ ! -d "$CONTEXT" ]; then
        log_error "Build context directory not found: $CONTEXT"
        exit 1
    fi

    log_success "Requirements check passed"
}

clean_old_images() {
    log_info "Cleaning up old images..."

    # Remove old tankstopp images (keep latest 3)
    OLD_IMAGES=$(docker images "$IMAGE_NAME" --format "{{.Repository}}:{{.Tag}}" | tail -n +4)
    if [ -n "$OLD_IMAGES" ]; then
        echo "$OLD_IMAGES" | xargs docker rmi -f 2>/dev/null || true
        log_success "Cleaned up old images"
    else
        log_info "No old images to clean"
    fi

    # Remove dangling images
    DANGLING=$(docker images -f "dangling=true" -q)
    if [ -n "$DANGLING" ]; then
        echo "$DANGLING" | xargs docker rmi -f 2>/dev/null || true
        log_success "Removed dangling images"
    fi
}

prepare_build_args() {
    log_info "Preparing build arguments..."

    # Add environment-specific build args
    case "$ENVIRONMENT" in
        "development")
            BUILD_ARGS="$BUILD_ARGS --build-arg APP_ENV=development"
            BUILD_ARGS="$BUILD_ARGS --build-arg DEBUG=true"
            ;;
        "production")
            BUILD_ARGS="$BUILD_ARGS --build-arg APP_ENV=production"
            BUILD_ARGS="$BUILD_ARGS --build-arg DEBUG=false"
            ;;
    esac

    # Add common build args
    BUILD_ARGS="$BUILD_ARGS --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
    BUILD_ARGS="$BUILD_ARGS --build-arg VCS_REF=$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')"
    BUILD_ARGS="$BUILD_ARGS --build-arg VERSION=$TAG"

    log_success "Build arguments prepared"
}

build_image() {
    log_info "Building Docker image..."
    log_info "Image: $IMAGE_NAME:$TAG"
    log_info "Environment: $ENVIRONMENT"
    log_info "Context: $CONTEXT"
    log_info "Dockerfile: $DOCKERFILE"

    # Construct docker build command
    DOCKER_CMD="docker build"

    # Add platform if specified
    if [ -n "$PLATFORM" ]; then
        DOCKER_CMD="$DOCKER_CMD --platform $PLATFORM"
    fi

    # Add no-cache flag if specified
    if [ "$NO_CACHE" = true ]; then
        DOCKER_CMD="$DOCKER_CMD --no-cache"
    fi

    # Add quiet flag if specified
    if [ "$QUIET" = true ]; then
        DOCKER_CMD="$DOCKER_CMD --quiet"
    fi

    # Add build arguments
    DOCKER_CMD="$DOCKER_CMD $BUILD_ARGS"

    # Add tag and file
    DOCKER_CMD="$DOCKER_CMD -t $IMAGE_NAME:$TAG"
    DOCKER_CMD="$DOCKER_CMD -f $DOCKERFILE"
    DOCKER_CMD="$DOCKER_CMD $CONTEXT"

    log_info "Executing: $DOCKER_CMD"

    # Execute build
    if eval "$DOCKER_CMD"; then
        log_success "Docker image built successfully: $IMAGE_NAME:$TAG"
    else
        log_error "Docker build failed"
        exit 1
    fi
}

push_image() {
    if [ "$PUSH" = true ]; then
        log_info "Pushing image to registry..."

        if docker push "$IMAGE_NAME:$TAG"; then
            log_success "Image pushed successfully: $IMAGE_NAME:$TAG"
        else
            log_error "Failed to push image"
            exit 1
        fi
    fi
}

show_image_info() {
    log_info "Image information:"
    docker images "$IMAGE_NAME:$TAG" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}"

    # Show image layers (if not quiet)
    if [ "$QUIET" != true ]; then
        echo ""
        log_info "Image layers:"
        docker history "$IMAGE_NAME:$TAG" --format "table {{.CreatedBy}}\t{{.Size}}" | head -10
    fi
}

main() {
    # Parse command line arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -t|--tag)
                TAG="$2"
                shift 2
                ;;
            -e|--env)
                ENVIRONMENT="$2"
                shift 2
                ;;
            -f|--file)
                DOCKERFILE="$2"
                shift 2
                ;;
            -c|--context)
                CONTEXT="$2"
                shift 2
                ;;
            -p|--platform)
                PLATFORM="$2"
                shift 2
                ;;
            --push)
                PUSH=true
                shift
                ;;
            --no-cache)
                NO_CACHE=true
                shift
                ;;
            --quiet)
                QUIET=true
                shift
                ;;
            --build-arg)
                BUILD_ARGS="$BUILD_ARGS --build-arg $2"
                shift 2
                ;;
            --clean)
                CLEAN=true
                shift
                ;;
            *)
                log_error "Unknown option: $1"
                show_help
                exit 1
                ;;
        esac
    done

    # Validate environment
    if [[ "$ENVIRONMENT" != "development" && "$ENVIRONMENT" != "production" ]]; then
        log_error "Invalid environment: $ENVIRONMENT. Must be 'development' or 'production'"
        exit 1
    fi

    # Start build process
    log_info "Starting TankStopp Docker build process..."

    check_requirements

    if [ "$CLEAN" = true ]; then
        clean_old_images
    fi

    prepare_build_args
    build_image
    push_image
    show_image_info

    log_success "Build process completed successfully!"
    log_info "You can now run the container with:"
    log_info "  docker run -p 8080:8080 $IMAGE_NAME:$TAG"
    log_info ""
    log_info "Or use docker-compose:"
    log_info "  docker-compose up -d"
}

# Execute main function
main "$@"
