#!/bin/bash

# AWS ECS Deployment Script for {{ project_name }}
# This script deploys the FastAPI application to AWS ECS

set -e

# Configuration
PROJECT_NAME="{{ project_name }}"
CLUSTER_NAME="${PROJECT_NAME}-cluster"
SERVICE_NAME="${PROJECT_NAME}-service"
TASK_DEFINITION="${PROJECT_NAME}-task"
REGION="${AWS_REGION:-us-east-1}"
IMAGE_TAG="${IMAGE_TAG:-latest}"
ECR_REPOSITORY="${ECR_REPOSITORY:-${PROJECT_NAME}}"

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

# Logging function
log() {
    echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1" >&2
}

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

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

# Check prerequisites
check_prerequisites() {
    log "Checking prerequisites..."
    
    if ! command -v aws &> /dev/null; then
        error "AWS CLI is not installed. Please install it first."
        exit 1
    fi
    
    if ! command -v docker &> /dev/null; then
        error "Docker is not installed. Please install it first."
        exit 1
    fi
    
    if ! aws sts get-caller-identity &> /dev/null; then
        error "AWS credentials not configured. Please run 'aws configure' first."
        exit 1
    fi
    
    success "Prerequisites check passed"
}

# Build and push Docker image
build_and_push_image() {
    log "Building Docker image..."
    
    # Build image
    docker build -t ${PROJECT_NAME}:${IMAGE_TAG} .
    
    # Get ECR login token
    aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com
    
    # Tag image for ECR
    docker tag ${PROJECT_NAME}:${IMAGE_TAG} ${AWS_ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}
    
    # Push image
    docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}
    
    success "Docker image built and pushed successfully"
}

# Create ECS cluster
create_cluster() {
    log "Creating ECS cluster..."
    
    if ! aws ecs describe-clusters --clusters ${CLUSTER_NAME} --region ${REGION} &> /dev/null; then
        aws ecs create-cluster \
            --cluster-name ${CLUSTER_NAME} \
            --region ${REGION} \
            --capacity-providers FARGATE \
            --default-capacity-provider-strategy capacityProvider=FARGATE,weight=1
        
        success "ECS cluster created: ${CLUSTER_NAME}"
    else
        warning "ECS cluster already exists: ${CLUSTER_NAME}"
    fi
}

# Create task definition
create_task_definition() {
    log "Creating ECS task definition..."
    
    cat > task-definition.json << EOF
{
    "family": "${TASK_DEFINITION}",
    "networkMode": "awsvpc",
    "requiresCompatibilities": ["FARGATE"],
    "cpu": "256",
    "memory": "512",
    "executionRoleArn": "arn:aws:iam::${AWS_ACCOUNT_ID}:role/ecsTaskExecutionRole",
    "containerDefinitions": [
        {
            "name": "${PROJECT_NAME}",
            "image": "${AWS_ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}",
            "portMappings": [
                {
                    "containerPort": 8000,
                    "protocol": "tcp"
                }
            ],
            "environment": [
                {
                    "name": "ENVIRONMENT",
                    "value": "production"
                }
            ],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/${PROJECT_NAME}",
                    "awslogs-region": "${REGION}",
                    "awslogs-stream-prefix": "ecs"
                }
            },
            "healthCheck": {
                "command": ["CMD-SHELL", "curl -f http://localhost:8000/api/v1/health || exit 1"],
                "interval": 30,
                "timeout": 5,
                "retries": 3,
                "startPeriod": 60
            }
        }
    ]
}
EOF
    
    aws ecs register-task-definition --cli-input-json file://task-definition.json --region ${REGION}
    
    success "Task definition created successfully"
}

# Create ECS service
create_service() {
    log "Creating ECS service..."
    
    if ! aws ecs describe-services --services ${SERVICE_NAME} --cluster ${CLUSTER_NAME} --region ${REGION} &> /dev/null; then
        aws ecs create-service \
            --cluster ${CLUSTER_NAME} \
            --service-name ${SERVICE_NAME} \
            --task-definition ${TASK_DEFINITION} \
            --desired-count 2 \
            --launch-type FARGATE \
            --network-configuration "awsvpcConfiguration={subnets=[${SUBNET_IDS}],securityGroups=[${SECURITY_GROUP_IDS}],assignPublicIp=ENABLED}" \
            --region ${REGION}
        
        success "ECS service created: ${SERVICE_NAME}"
    else
        warning "ECS service already exists: ${SERVICE_NAME}"
    fi
}

# Update service
update_service() {
    log "Updating ECS service..."
    
    aws ecs update-service \
        --cluster ${CLUSTER_NAME} \
        --service ${SERVICE_NAME} \
        --task-definition ${TASK_DEFINITION} \
        --region ${REGION}
    
    success "Service updated successfully"
}

# Wait for service stability
wait_for_stability() {
    log "Waiting for service to become stable..."
    
    aws ecs wait services-stable \
        --cluster ${CLUSTER_NAME} \
        --services ${SERVICE_NAME} \
        --region ${REGION}
    
    success "Service is now stable"
}

# Health check
health_check() {
    log "Performing health check..."
    
    # Get service URL (you'll need to configure this based on your setup)
    if [ -n "${SERVICE_URL}" ]; then
        if curl -f ${SERVICE_URL}/api/v1/health; then
            success "Health check passed"
        else
            error "Health check failed"
            exit 1
        fi
    else
        warning "SERVICE_URL not set, skipping health check"
    fi
}

# Main deployment function
deploy() {
    log "Starting deployment for ${PROJECT_NAME}..."
    
    check_prerequisites
    build_and_push_image
    create_cluster
    create_task_definition
    create_service
    update_service
    wait_for_stability
    health_check
    
    success "Deployment completed successfully!"
    log "Service URL: ${SERVICE_URL:-'Not configured'}"
    log "ECS Cluster: ${CLUSTER_NAME}"
    log "ECS Service: ${SERVICE_NAME}"
}

# Rollback function
rollback() {
    log "Rolling back deployment..."
    
    # Get previous task definition
    PREVIOUS_TASK_DEF=$(aws ecs describe-services \
        --cluster ${CLUSTER_NAME} \
        --services ${SERVICE_NAME} \
        --region ${REGION} \
        --query 'services[0].taskDefinition' \
        --output text)
    
    if [ "${PREVIOUS_TASK_DEF}" != "None" ]; then
        aws ecs update-service \
            --cluster ${CLUSTER_NAME} \
            --service ${SERVICE_NAME} \
            --task-definition ${PREVIOUS_TASK_DEF} \
            --region ${REGION}
        
        success "Rollback completed"
    else
        error "No previous task definition found for rollback"
    fi
}

# Show usage
usage() {
    echo "Usage: $0 [deploy|rollback|health-check]"
    echo ""
    echo "Commands:"
    echo "  deploy       - Deploy the application to ECS"
    echo "  rollback     - Rollback to previous deployment"
    echo "  health-check - Perform health check on deployed service"
    echo ""
    echo "Environment variables:"
    echo "  AWS_REGION           - AWS region (default: us-east-1)"
    echo "  AWS_ACCOUNT_ID      - AWS account ID"
    echo "  IMAGE_TAG           - Docker image tag (default: latest)"
    echo "  ECR_REPOSITORY      - ECR repository name (default: project name)"
    echo "  SUBNET_IDS          - Comma-separated subnet IDs"
    echo "  SECURITY_GROUP_IDS  - Comma-separated security group IDs"
    echo "  SERVICE_URL         - Service URL for health checks"
}

# Main script logic
case "${1:-deploy}" in
    deploy)
        deploy
        ;;
    rollback)
        rollback
        ;;
    health-check)
        health_check
        ;;
    *)
        usage
        exit 1
        ;;
esac
