#!/bin/bash

# Payment Service Deployment Script
# This script automates the deployment of the payment service

set -e

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

# Configuration
SERVICE_NAME="payment-service"
NAMESPACE="payment"
IMAGE_TAG="latest"
REGISTRY="your-registry.com"

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

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

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

# Check if required tools are installed
check_prerequisites() {
    log_info "Checking prerequisites..."
    
    if ! command -v docker &> /dev/null; then
        log_error "Docker is not installed"
        exit 1
    fi
    
    if ! command -v kubectl &> /dev/null; then
        log_error "kubectl is not installed"
        exit 1
    fi
    
    if ! command -v helm &> /dev/null; then
        log_warn "Helm is not installed, skipping Helm deployment"
    fi
    
    log_info "Prerequisites check completed"
}

# Build Docker image
build_image() {
    log_info "Building Docker image..."
    
    docker build -t ${SERVICE_NAME}:${IMAGE_TAG} .
    
    if [ $? -eq 0 ]; then
        log_info "Docker image built successfully"
    else
        log_error "Failed to build Docker image"
        exit 1
    fi
}

# Push image to registry
push_image() {
    if [ -n "$REGISTRY" ]; then
        log_info "Pushing image to registry..."
        
        docker tag ${SERVICE_NAME}:${IMAGE_TAG} ${REGISTRY}/${SERVICE_NAME}:${IMAGE_TAG}
        docker push ${REGISTRY}/${SERVICE_NAME}:${IMAGE_TAG}
        
        if [ $? -eq 0 ]; then
            log_info "Image pushed successfully"
        else
            log_error "Failed to push image"
            exit 1
        fi
    else
        log_warn "No registry specified, skipping image push"
    fi
}

# Create namespace
create_namespace() {
    log_info "Creating namespace..."
    
    kubectl create namespace ${NAMESPACE} --dry-run=client -o yaml | kubectl apply -f -
    
    log_info "Namespace created/verified"
}

# Deploy to Kubernetes
deploy_k8s() {
    log_info "Deploying to Kubernetes..."
    
    # Update image in deployment.yaml if registry is specified
    if [ -n "$REGISTRY" ]; then
        sed -i "s|image: payment-service:latest|image: ${REGISTRY}/${SERVICE_NAME}:${IMAGE_TAG}|g" k8s/deployment.yaml
    fi
    
    # Apply Kubernetes manifests
    kubectl apply -f k8s/ -n ${NAMESPACE}
    
    # Wait for deployment to be ready
    kubectl wait --for=condition=available --timeout=300s deployment/${SERVICE_NAME} -n ${NAMESPACE}
    
    log_info "Kubernetes deployment completed"
}

# Run tests
run_tests() {
    log_info "Running tests..."
    
    go test ./...
    
    if [ $? -eq 0 ]; then
        log_info "Tests passed"
    else
        log_error "Tests failed"
        exit 1
    fi
}

# Health check
health_check() {
    log_info "Performing health check..."
    
    # Get service URL
    SERVICE_URL=$(kubectl get service ${SERVICE_NAME} -n ${NAMESPACE} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    
    if [ -z "$SERVICE_URL" ]; then
        SERVICE_URL="localhost:8080"
    fi
    
    # Wait for service to be ready
    for i in {1..30}; do
        if curl -f http://${SERVICE_URL}/health > /dev/null 2>&1; then
            log_info "Health check passed"
            return 0
        fi
        log_info "Waiting for service to be ready... (attempt $i/30)"
        sleep 10
    done
    
    log_error "Health check failed"
    exit 1
}

# Cleanup function
cleanup() {
    log_info "Cleaning up..."
    # Add cleanup logic here if needed
}

# Main deployment function
deploy() {
    log_info "Starting deployment of ${SERVICE_NAME}..."
    
    check_prerequisites
    run_tests
    build_image
    push_image
    create_namespace
    deploy_k8s
    health_check
    
    log_info "Deployment completed successfully!"
    log_info "Service is available at: http://${SERVICE_URL}"
}

# Rollback function
rollback() {
    log_info "Rolling back deployment..."
    
    kubectl rollout undo deployment/${SERVICE_NAME} -n ${NAMESPACE}
    kubectl rollout status deployment/${SERVICE_NAME} -n ${NAMESPACE}
    
    log_info "Rollback completed"
}

# Scale function
scale() {
    REPLICAS=${1:-3}
    log_info "Scaling deployment to ${REPLICAS} replicas..."
    
    kubectl scale deployment/${SERVICE_NAME} --replicas=${REPLICAS} -n ${NAMESPACE}
    kubectl rollout status deployment/${SERVICE_NAME} -n ${NAMESPACE}
    
    log_info "Scaling completed"
}

# Show usage
usage() {
    echo "Usage: $0 [COMMAND]"
    echo ""
    echo "Commands:"
    echo "  deploy     Deploy the service"
    echo "  rollback   Rollback the deployment"
    echo "  scale N    Scale to N replicas"
    echo "  test       Run tests only"
    echo "  build      Build Docker image only"
    echo "  help       Show this help message"
}

# Main script logic
case "${1:-deploy}" in
    deploy)
        deploy
        ;;
    rollback)
        rollback
        ;;
    scale)
        scale $2
        ;;
    test)
        run_tests
        ;;
    build)
        build_image
        ;;
    help)
        usage
        ;;
    *)
        log_error "Unknown command: $1"
        usage
        exit 1
        ;;
esac
