#!/bin/bash
#
# Deployment script for mockupAWS
# Usage: ./deploy.sh [environment] [version]
#

set -euo pipefail

# Configuration
ENVIRONMENT=${1:-production}
VERSION=${2:-latest}
PROJECT_NAME="mockupaws"
AWS_REGION="us-east-1"

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

# Logging 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 prerequisites
check_prerequisites() {
    log_info "Checking prerequisites..."
    
    # Check AWS CLI
    if ! command -v aws &> /dev/null; then
        log_error "AWS CLI is not installed"
        exit 1
    fi
    
    # Check Docker
    if ! command -v docker &> /dev/null; then
        log_error "Docker is not installed"
        exit 1
    fi
    
    # Check AWS credentials
    if ! aws sts get-caller-identity &> /dev/null; then
        log_error "AWS credentials not configured"
        exit 1
    fi
    
    log_info "Prerequisites check passed"
}

# Deploy to ECS
deploy_ecs() {
    log_info "Deploying to ECS ($ENVIRONMENT)..."
    
    CLUSTER_NAME="${PROJECT_NAME}-${ENVIRONMENT}"
    SERVICE_NAME="backend"
    
    # Update service
    aws ecs update-service \
        --cluster "$CLUSTER_NAME" \
        --service "$SERVICE_NAME" \
        --force-new-deployment \
        --region "$AWS_REGION"
    
    log_info "Waiting for service to stabilize..."
    aws ecs wait services-stable \
        --cluster "$CLUSTER_NAME" \
        --services "$SERVICE_NAME" \
        --region "$AWS_REGION"
    
    log_info "ECS deployment complete"
}

# Deploy to Docker Compose (Single Server)
deploy_docker_compose() {
    log_info "Deploying with Docker Compose ($ENVIRONMENT)..."
    
    COMPOSE_FILE="docker-compose.${ENVIRONMENT}.yml"
    
    if [ ! -f "$COMPOSE_FILE" ]; then
        log_error "Compose file not found: $COMPOSE_FILE"
        exit 1
    fi
    
    # Pull latest images
    log_info "Pulling latest images..."
    docker-compose -f "$COMPOSE_FILE" pull
    
    # Run migrations
    log_info "Running database migrations..."
    docker-compose -f "$COMPOSE_FILE" run --rm backend alembic upgrade head
    
    # Deploy
    log_info "Starting services..."
    docker-compose -f "$COMPOSE_FILE" up -d
    
    # Health check
    log_info "Performing health check..."
    sleep 10
    
    MAX_RETRIES=30
    RETRY_COUNT=0
    
    while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
        if curl -f http://localhost:8000/api/v1/health > /dev/null 2>&1; then
            log_info "Health check passed"
            break
        fi
        
        RETRY_COUNT=$((RETRY_COUNT + 1))
        log_warn "Health check attempt $RETRY_COUNT/$MAX_RETRIES failed, retrying..."
        sleep 5
    done
    
    if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
        log_error "Health check failed after $MAX_RETRIES attempts"
        exit 1
    fi
    
    # Cleanup old images
    log_info "Cleaning up old images..."
    docker image prune -f
    
    log_info "Docker Compose deployment complete"
}

# Blue-Green Deployment
deploy_blue_green() {
    log_info "Starting blue-green deployment..."
    
    CLUSTER_NAME="${PROJECT_NAME}-${ENVIRONMENT}"
    SERVICE_NAME="backend"
    
    # Get current task definition
    CURRENT_TASK_DEF=$(aws ecs describe-services \
        --cluster "$CLUSTER_NAME" \
        --services "$SERVICE_NAME" \
        --query 'services[0].taskDefinition' \
        --output text \
        --region "$AWS_REGION")
    
    log_info "Current task definition: $CURRENT_TASK_DEF"
    
    # Register new task definition with blue/green labels
    NEW_TASK_DEF=$(aws ecs describe-task-definition \
        --task-definition "$CURRENT_TASK_DEF" \
        --query 'taskDefinition' \
        --region "$AWS_REGION" | \
        jq '.family = "'"$SERVICE_NAME"'-green" | del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)')
    
    echo "$NEW_TASK_DEF" > /tmp/new-task-def.json
    
    NEW_TASK_DEF_ARN=$(aws ecs register-task-definition \
        --cli-input-json file:///tmp/new-task-def.json \
        --query 'taskDefinition.taskDefinitionArn' \
        --output text \
        --region "$AWS_REGION")
    
    log_info "Registered new task definition: $NEW_TASK_DEF_ARN"
    
    # Create green service
    GREEN_SERVICE_NAME="${SERVICE_NAME}-green"
    
    aws ecs create-service \
        --cluster "$CLUSTER_NAME" \
        --service-name "$GREEN_SERVICE_NAME" \
        --task-definition "$NEW_TASK_DEF_ARN" \
        --desired-count 2 \
        --launch-type FARGATE \
        --network-configuration "awsvpcConfiguration={subnets=[$(aws ecs describe-services --cluster $CLUSTER_NAME --services $SERVICE_NAME --query 'services[0].networkConfiguration.awsvpcConfiguration.subnets' --output text --region $AWS_REGION)],securityGroups=[$(aws ecs describe-services --cluster $CLUSTER_NAME --services $SERVICE_NAME --query 'services[0].networkConfiguration.awsvpcConfiguration.securityGroups' --output text --region $AWS_REGION)],assignPublicIp=DISABLED}" \
        --region "$AWS_REGION" 2>/dev/null || \
    aws ecs update-service \
        --cluster "$CLUSTER_NAME" \
        --service "$GREEN_SERVICE_NAME" \
        --task-definition "$NEW_TASK_DEF_ARN" \
        --force-new-deployment \
        --region "$AWS_REGION"
    
    log_info "Waiting for green service to stabilize..."
    aws ecs wait services-stable \
        --cluster "$CLUSTER_NAME" \
        --services "$GREEN_SERVICE_NAME" \
        --region "$AWS_REGION"
    
    # Health check on green
    log_info "Performing health check on green service..."
    # Note: In production, you'd use the green service endpoint
    sleep 10
    
    # Switch traffic (in production, update ALB target group)
    log_info "Switching traffic to green service..."
    
    # Update blue service to match green
    aws ecs update-service \
        --cluster "$CLUSTER_NAME" \
        --service "$SERVICE_NAME" \
        --task-definition "$NEW_TASK_DEF_ARN" \
        --force-new-deployment \
        --region "$AWS_REGION"
    
    log_info "Waiting for blue service to stabilize..."
    aws ecs wait services-stable \
        --cluster "$CLUSTER_NAME" \
        --services "$SERVICE_NAME" \
        --region "$AWS_REGION"
    
    # Remove green service
    log_info "Removing green service..."
    aws ecs delete-service \
        --cluster "$CLUSTER_NAME" \
        --service "$GREEN_SERVICE_NAME" \
        --force \
        --region "$AWS_REGION"
    
    log_info "Blue-green deployment complete"
}

# Rollback deployment
rollback() {
    log_warn "Initiating rollback..."
    
    CLUSTER_NAME="${PROJECT_NAME}-${ENVIRONMENT}"
    SERVICE_NAME="backend"
    
    # Get previous task definition
    TASK_DEFS=$(aws ecs list-task-definitions \
        --family-prefix "$SERVICE_NAME" \
        --sort DESC \
        --query 'taskDefinitionArns[1]' \
        --output text \
        --region "$AWS_REGION")
    
    if [ -z "$TASK_DEFS" ] || [ "$TASK_DEFS" = "None" ]; then
        log_error "No previous task definition found for rollback"
        exit 1
    fi
    
    log_info "Rolling back to: $TASK_DEFS"
    
    # Update service to previous revision
    aws ecs update-service \
        --cluster "$CLUSTER_NAME" \
        --service "$SERVICE_NAME" \
        --task-definition "$TASK_DEFS" \
        --force-new-deployment \
        --region "$AWS_REGION"
    
    log_info "Waiting for rollback to complete..."
    aws ecs wait services-stable \
        --cluster "$CLUSTER_NAME" \
        --services "$SERVICE_NAME" \
        --region "$AWS_REGION"
    
    log_info "Rollback complete"
}

# Main deployment logic
main() {
    log_info "Starting deployment: $PROJECT_NAME $VERSION to $ENVIRONMENT"
    
    check_prerequisites
    
    case "${DEPLOYMENT_TYPE:-ecs}" in
        ecs)
            deploy_ecs
            ;;
        docker-compose)
            deploy_docker_compose
            ;;
        blue-green)
            deploy_blue_green
            ;;
        rollback)
            rollback
            ;;
        *)
            log_error "Unknown deployment type: $DEPLOYMENT_TYPE"
            log_info "Supported types: ecs, docker-compose, blue-green, rollback"
            exit 1
            ;;
    esac
    
    log_info "Deployment completed successfully!"
}

# Show usage
usage() {
    echo "Usage: $0 [environment] [version]"
    echo ""
    echo "Arguments:"
    echo "  environment    Target environment (dev, staging, production)"
    echo "  version        Version to deploy (default: latest)"
    echo ""
    echo "Environment Variables:"
    echo "  DEPLOYMENT_TYPE   Deployment method (ecs, docker-compose, blue-green, rollback)"
    echo "  AWS_REGION        AWS region (default: us-east-1)"
    echo ""
    echo "Examples:"
    echo "  $0 production v1.0.0"
    echo "  DEPLOYMENT_TYPE=docker-compose $0 production"
    echo "  DEPLOYMENT_TYPE=rollback $0 production"
}

# Handle arguments
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
    usage
    exit 0
fi

# Run main function
main
