services:
  # Load Balancer (NGINX) with WebSocket support and session persistence
  load-balancer:
    image: nginx:latest
    container_name: load-balancer
    ports:
      - "4000:80"  # External port 4000 maps to NGINX's port 80
    volumes:
      - ./nginx-websocket.conf:/etc/nginx/nginx.conf:ro  # Mount NGINX configuration
    networks:
      - redis-cluster-net
    depends_on:
      - node-app-1
      - node-app-2
      - node-app-3
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost/health" ]
      interval: 10s
      timeout: 5s
      retries: 5

  # Node App Instance 1
  node-app-1:
    build:
      context: .
    container_name: node-app-1
    hostname: node-app-1
    networks:
      - redis-cluster-net
    env_file:
      - .env.development
    depends_on:
      redis-node-1:
        condition: service_healthy
      redis-node-2:
        condition: service_healthy
      redis-node-3:
        condition: service_healthy
      localstack:
        condition: service_healthy
      aws-cli:
        condition: service_completed_successfully
    ports:
      - "4001:4000"  # Different external port for local access
    volumes:
      - .:/app
      - node-app-npm-cache:/app/node_modules

  # Node App Instance 2
  node-app-2:
    build:
      context: .
    container_name: node-app-2
    hostname: node-app-2
    networks:
      - redis-cluster-net
    env_file:
      - .env.development
    depends_on:
      redis-node-1:
        condition: service_healthy
      redis-node-2:
        condition: service_healthy
      redis-node-3:
        condition: service_healthy
      localstack:
        condition: service_healthy
      aws-cli:
        condition: service_completed_successfully
    ports:
      - "4002:4000"  # Different external port for local access
    volumes:
      - .:/app
      - node-app-npm-cache:/app/node_modules

  # Node App Instance 3
  node-app-3:
    build:
      context: .
    container_name: node-app-3
    hostname: node-app-3
    networks:
      - redis-cluster-net
    env_file:
      - .env.development
    depends_on:
      redis-node-1:
        condition: service_healthy
      redis-node-2:
        condition: service_healthy
      redis-node-3:
        condition: service_healthy
      localstack:
        condition: service_healthy
      aws-cli:
        condition: service_completed_successfully
    ports:
      - "4003:4000"  # Different external port for local access
    volumes:
      - .:/app
      - node-app-npm-cache:/app/node_modules

  # Redis Node 1 
  redis-node-1:
    build:
      context: ./redis
    container_name: redis-node-1
    hostname: redis-node-1
    restart: unless-stopped
    networks:
      - redis-cluster-net
    volumes:
      - redis-node-1-data:/data
      - redis-lock:/redis-lock
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 10s
      timeout: 5s
      retries: 10

  # Redis Node 2  
  redis-node-2:
    build:
      context: ./redis
    container_name: redis-node-2
    hostname: redis-node-2
    restart: unless-stopped
    networks:
      - redis-cluster-net
    volumes:
      - redis-node-2-data:/data
      - redis-lock:/redis-lock
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 10s
      timeout: 5s
      retries: 10

  # Redis Node 3
  redis-node-3:
    build:
      context: ./redis
    container_name: redis-node-3
    hostname: redis-node-3
    restart: unless-stopped
    networks:
      - redis-cluster-net
    volumes:
      - redis-node-3-data:/data
      - redis-lock:/redis-lock
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 10s
      timeout: 5s
      retries: 10

  # LocalStack
  localstack:
    image: localstack/localstack
    container_name: localstack
    hostname: localstack
    networks:
      - redis-cluster-net
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - SERVICES=s3,ses,secretsmanager,cloudwatch,logs
      - DEBUG=0
      - AWS_ACCESS_KEY_ID=test
      - AWS_SECRET_ACCESS_KEY=test
      - AWS_DEFAULT_REGION=ca-central-1
      - EXTRA_CORS_ALLOWED_HEADERS=Authorization,Content-Type
      - EXTRA_CORS_ALLOWED_ORIGINS=*
      - EXTRA_CORS_EXPOSE_HEADERS=Authorization,Content-Type
    ports:
      - "4566:4566"
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:4566/_localstack/health" ]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 20s

  # AWS-CLI
  aws-cli:
    image: amazon/aws-cli
    container_name: aws-cli
    hostname: aws-cli
    networks:
      - redis-cluster-net
    depends_on:
      localstack:
        condition: service_healthy
    volumes:
      - './localstack:/tmp/localstack'
      - './certs:/tmp/certs'
    environment:
      - AWS_ACCESS_KEY_ID=test
      - AWS_SECRET_ACCESS_KEY=test
      - AWS_DEFAULT_REGION=ca-central-1
    entrypoint: /bin/sh -c
    command: >
      "
        aws --endpoint-url=http://localstack:4566 ses verify-domain-identity --domain imex.online --region ca-central-1
        aws --endpoint-url=http://localstack:4566 ses verify-email-identity --email-address noreply@imex.online --region ca-central-1
        aws --endpoint-url=http://localstack:4566 secretsmanager create-secret --name CHATTER_PRIVATE_KEY --secret-string file:///tmp/certs/io-ftp-test.key
        aws --endpoint-url=http://localstack:4566 logs create-log-group --log-group-name development --region ca-central-1
        aws --endpoint-url=http://localstack:4566 s3api create-bucket --bucket imex-large-log --create-bucket-configuration LocationConstraint=ca-central-1
      "

networks:
  redis-cluster-net:
    driver: bridge

volumes:
  node-app-npm-cache:
  redis-node-1-data:
  redis-node-2-data:
  redis-node-3-data:
  redis-lock:
