#!/bin/bash

# Deployment script for MerchantsOfHope.org
# This script handles the deployment process to Kubernetes

set -e  # Exit immediately if a command exits with a non-zero status

# Configuration
NAMESPACE="merchantsofhope"
IMAGE_NAME="qwen-hack-moh"
IMAGE_TAG="latest"
HELM_RELEASE_NAME="moh-app"
HELM_CHART_PATH="./helm/moh-app"

# Function to print messages
print_msg() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}

# Function to check prerequisites
check_prerequisites() {
    print_msg "Checking prerequisites..."

    # Check if kubectl is installed
    if ! command -v kubectl &> /dev/null; then
        echo "kubectl is not installed. Please install kubectl and try again."
        exit 1
    fi

    # Check if helm is installed
    if ! command -v helm &> /dev/null; then
        echo "helm is not installed. Please install helm and try again."
        exit 1
    fi

    # Check if docker is installed and running
    if ! command -v docker &> /dev/null; then
        echo "docker is not installed. Please install docker and try again."
        exit 1
    fi

    if ! docker info &> /dev/null; then
        echo "docker is not running. Please start docker and try again."
        exit 1
    fi

    print_msg "All prerequisites are satisfied."
}

# Function to build the Docker image
build_image() {
    print_msg "Building Docker image: ${IMAGE_NAME}:${IMAGE_TAG}"

    docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .
    
    if [ $? -ne 0 ]; then
        print_msg "Failed to build Docker image"
        exit 1
    fi

    print_msg "Docker image built successfully"
}

# Function to push the Docker image
push_image() {
    print_msg "Pushing Docker image: ${IMAGE_NAME}:${IMAGE_TAG}"

    # Tag with git commit hash if available
    GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "dev")
    docker tag ${IMAGE_NAME}:${IMAGE_TAG} ${IMAGE_NAME}:${GIT_COMMIT}
    
    # Push both tags
    docker push ${IMAGE_NAME}:${IMAGE_TAG}
    docker push ${IMAGE_NAME}:${GIT_COMMIT}
    
    if [ $? -ne 0 ]; then
        print_msg "Failed to push Docker image"
        exit 1
    fi

    print_msg "Docker image pushed successfully"
}

# Function to create namespace
create_namespace() {
    print_msg "Creating namespace: ${NAMESPACE}"

    kubectl get namespace ${NAMESPACE} &> /dev/null || kubectl create namespace ${NAMESPACE}
    
    print_msg "Namespace created or already exists"
}

# Function to deploy using Helm
deploy_helm() {
    print_msg "Deploying using Helm..."

    # Check if the release already exists
    if helm status ${HELM_RELEASE_NAME} -n ${NAMESPACE} &> /dev/null; then
        print_msg "Helm release exists, upgrading..."
        helm upgrade ${HELM_RELEASE_NAME} ${HELM_CHART_PATH} --namespace ${NAMESPACE} --wait
    else
        print_msg "Installing Helm release..."
        helm install ${HELM_RELEASE_NAME} ${HELM_CHART_PATH} --namespace ${NAMESPACE} --create-namespace --wait
    fi

    if [ $? -ne 0 ]; then
        print_msg "Failed to deploy with Helm"
        exit 1
    fi

    print_msg "Helm deployment completed successfully"
}

# Function to verify the deployment
verify_deployment() {
    print_msg "Verifying deployment..."

    # Wait for pods to be ready
    kubectl wait --for=condition=ready pod -l app=moh-app -n ${NAMESPACE} --timeout=300s

    if [ $? -ne 0 ]; then
        print_msg "Deployment verification failed"
        exit 1
    fi

    print_msg "Deployment verification completed successfully"
}

# Function to show deployment status
show_status() {
    print_msg "Deployment status:"
    kubectl get pods -n ${NAMESPACE}
    kubectl get services -n ${NAMESPACE}
    kubectl get ingress -n ${NAMESPACE}
}

# Function to run tests
run_tests() {
    print_msg "Running tests..."

    # Run unit tests
    vendor/bin/phpunit --configuration phpunit.xml --coverage-text

    if [ $? -ne 0 ]; then
        print_msg "Tests failed"
        exit 1
    fi

    print_msg "All tests passed"
}

# Main execution
main() {
    print_msg "Starting deployment process for MerchantsOfHope.org"

    # Parse command line arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            --build-only)
                build_image
                exit 0
                ;;
            --push-only)
                push_image
                exit 0
                ;;
            --deploy-only)
                check_prerequisites
                create_namespace
                deploy_helm
                verify_deployment
                show_status
                exit 0
                ;;
            --test-only)
                run_tests
                exit 0
                ;;
            --help)
                echo "Usage: $0 [OPTIONS]"
                echo "Options:"
                echo "  --build-only    Only build the Docker image"
                echo "  --push-only     Only push the Docker image"
                echo "  --deploy-only   Only deploy to Kubernetes"
                echo "  --test-only     Only run tests"
                echo "  --help          Show this help"
                exit 0
                ;;
            *)
                echo "Unknown option: $1"
                echo "Use --help for usage information"
                exit 1
                ;;
        esac
        shift
    done

    # Execute full deployment process
    check_prerequisites
    run_tests
    build_image
    push_image
    create_namespace
    deploy_helm
    verify_deployment
    show_status

    print_msg "Deployment completed successfully!"
    print_msg "Access the application at: https://merchantsofhope.org"
}

# Execute main function with all arguments
main "$@"