#!/usr/bin/env bash

# services-compose.sh - Generate docker-compose.yml for services

# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Source environment utilities for safe loading
source "$SCRIPT_DIR/../../lib/utils/env.sh"
source "$SCRIPT_DIR/../../lib/utils/display.sh"

# Load environment safely (without executing JSON values)
if [ -f ".env.local" ]; then
  load_env_with_priority ".env.local"
else
  echo "Error: No .env.local file found."
  exit 1
fi

TEMPLATES_DIR="$SCRIPT_DIR/../../templates/services"

# Start building docker-compose.yml
cat >docker-compose.yml <<EOF
# Services Docker Compose
# This file is auto-generated by nself build

version: '3.8'

services:
EOF

# NestJS Services
if [[ "$NESTJS_ENABLED" == "true" ]]; then
  IFS=',' read -ra NEST_SERVICES <<<"$NESTJS_SERVICES"
  PORT_COUNTER=0

  for service in "${NEST_SERVICES[@]}"; do
    service=$(echo "$service" | xargs)
    SERVICE_PORT=$((NESTJS_PORT_START + PORT_COUNTER))

    cat >>docker-compose.yml <<EOF

  # NestJS Service: $service
  nest-$service:
    build:
      context: ./nest/$service
      dockerfile: Dockerfile
    container_name: \${PROJECT_NAME}_nest_$service
    restart: unless-stopped
    environment:
      - NODE_ENV=\${ENVIRONMENT}
      - PORT=$SERVICE_PORT
      - DATABASE_URL=\${DATABASE_URL}
      - HASURA_ENDPOINT=\${HASURA_ENDPOINT}
      - HASURA_ADMIN_SECRET=\${HASURA_ADMIN_SECRET}
      - REDIS_HOST=\${REDIS_HOST}
      - REDIS_PORT=\${REDIS_PORT}
      - CORS_ORIGINS=\${CORS_ORIGINS}
    ports:
      - "$SERVICE_PORT:$SERVICE_PORT"
    depends_on:
      - postgres
      - hasura
    networks:
      - \${PROJECT_NAME}_network
    volumes:
      - ./nest/$service/src:/app/src:ro
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:$SERVICE_PORT/health"]
      interval: 30s
      timeout: 10s
      retries: 3
EOF

    PORT_COUNTER=$((PORT_COUNTER + 1))
  done
fi

# BullMQ Workers
if [[ "$BULLMQ_ENABLED" == "true" ]]; then
  IFS=',' read -ra BULLMQ_WORKER_LIST <<<"$BULLMQ_WORKERS"

  for worker in "${BULLMQ_WORKER_LIST[@]}"; do
    worker=$(echo "$worker" | xargs)

    cat >>docker-compose.yml <<EOF

  # BullMQ Worker: $worker
  bullmq-$worker:
    build:
      context: ./bullmq/$worker
      dockerfile: Dockerfile
    container_name: \${PROJECT_NAME}_bullmq_$worker
    restart: unless-stopped
    environment:
      - NODE_ENV=\${ENVIRONMENT}
      - REDIS_HOST=\${REDIS_HOST}
      - REDIS_PORT=\${REDIS_PORT}
      - REDIS_PASSWORD=\${REDIS_PASSWORD}
      - BULLMQ_DASHBOARD_ENABLED=\${BULLMQ_DASHBOARD_ENABLED}
      - BULLMQ_DASHBOARD_PORT=\${BULLMQ_DASHBOARD_PORT}
      - DATABASE_URL=\${DATABASE_URL}
      - HASURA_ENDPOINT=\${HASURA_ENDPOINT}
      - HASURA_ADMIN_SECRET=\${HASURA_ADMIN_SECRET}
EOF

    if [[ "$BULLMQ_DASHBOARD_ENABLED" == "true" ]]; then
      cat >>docker-compose.yml <<EOF
    ports:
      - "\${BULLMQ_DASHBOARD_PORT}:\${BULLMQ_DASHBOARD_PORT}"
EOF
    fi

    cat >>docker-compose.yml <<EOF
    depends_on:
      - redis
    networks:
      - \${PROJECT_NAME}_network
    volumes:
      - ./bullmq/$worker:/app:ro
    healthcheck:
      test: ["CMD", "node", "-e", "const redis = require('ioredis'); const client = new redis(process.env.REDIS_HOST || 'redis', process.env.REDIS_PORT || 6379); client.ping().then(() => process.exit(0)).catch(() => process.exit(1))"]
      interval: 30s
      timeout: 10s
      retries: 3
EOF
  done
fi

# GoLang Services
if [[ "$GOLANG_ENABLED" == "true" ]]; then
  IFS=',' read -ra GO_SERVICES <<<"$GOLANG_SERVICES"
  PORT_COUNTER=0

  for service in "${GO_SERVICES[@]}"; do
    service=$(echo "$service" | xargs)
    SERVICE_PORT=$((GOLANG_PORT_START + PORT_COUNTER))

    cat >>docker-compose.yml <<EOF

  # GoLang Service: $service
  go-$service:
    build:
      context: ./go/$service
      dockerfile: Dockerfile
    container_name: \${PROJECT_NAME}_go_$service
    restart: unless-stopped
    environment:
      - GO_ENV=\${ENVIRONMENT}
      - PORT=$SERVICE_PORT
      - DATABASE_URL=\${DATABASE_URL}
      - HASURA_ENDPOINT=\${HASURA_ENDPOINT}
      - HASURA_ADMIN_SECRET=\${HASURA_ADMIN_SECRET}
      - REDIS_HOST=\${REDIS_HOST}
      - REDIS_PORT=\${REDIS_PORT}
    ports:
      - "$SERVICE_PORT:$SERVICE_PORT"
    depends_on:
      - postgres
      - hasura
    networks:
      - \${PROJECT_NAME}_network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:$SERVICE_PORT/health"]
      interval: 30s
      timeout: 10s
      retries: 3
EOF

    PORT_COUNTER=$((PORT_COUNTER + 1))
  done
fi

# Python Services
if [[ "$PYTHON_ENABLED" == "true" ]]; then
  IFS=',' read -ra PY_SERVICES <<<"$PYTHON_SERVICES"
  PORT_COUNTER=0

  for service in "${PY_SERVICES[@]}"; do
    service=$(echo "$service" | xargs)
    SERVICE_PORT=$((PYTHON_PORT_START + PORT_COUNTER))

    cat >>docker-compose.yml <<EOF

  # Python Service: $service
  py-$service:
    build:
      context: ./py/$service
      dockerfile: Dockerfile
    container_name: \${PROJECT_NAME}_py_$service
    restart: unless-stopped
    environment:
      - PYTHON_ENV=\${ENVIRONMENT}
      - PORT=$SERVICE_PORT
      - DATABASE_URL=\${DATABASE_URL}
      - HASURA_ENDPOINT=\${HASURA_ENDPOINT}
      - HASURA_ADMIN_SECRET=\${HASURA_ADMIN_SECRET}
      - REDIS_HOST=\${REDIS_HOST}
      - REDIS_PORT=\${REDIS_PORT}
    ports:
      - "$SERVICE_PORT:$SERVICE_PORT"
    depends_on:
      - postgres
      - hasura
    networks:
      - \${PROJECT_NAME}_network
    volumes:
      - ./py/$service:/app:ro
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:$SERVICE_PORT/health"]
      interval: 30s
      timeout: 10s
      retries: 3
EOF

    PORT_COUNTER=$((PORT_COUNTER + 1))
  done
fi

# Add networks and volumes section
cat >>docker-compose.yml <<EOF

networks:
  \${PROJECT_NAME}_network:
    name: \${PROJECT_NAME}_network
    external: true

volumes:
  services_data:
    name: \${PROJECT_NAME}_services_data
EOF

echo "docker-compose.yml generated successfully!"
