version: '3.8'

# ==============================================================================
# Goa GEL Platform - Docker Compose
# ==============================================================================
#
# Quick Start (no config needed):
#   docker-compose up -d
#
# Production: Copy .env.example to .env and update security values
#
# Services:
#   - Frontend:   http://localhost:4200
#   - API:        http://localhost:3001
#   - Blockscout: http://localhost:4000
#   - MinIO:      http://localhost:9001 (admin console)
#
# ==============================================================================

services:
  # ================================
  # PostgreSQL Database
  # ================================
  postgres:
    image: postgres:15-alpine
    container_name: goa-gel-postgres
    restart: unless-stopped
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: goa_gel_platform
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-postgres_dev_password}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - goa-gel-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d goa_gel_platform"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ================================
  # Redis Cache & Queue
  # ================================
  redis:
    image: redis:7-alpine
    container_name: goa-gel-redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - goa-gel-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ================================
  # MinIO Object Storage
  # ================================
  minio:
    image: minio/minio:latest
    container_name: goa-gel-minio
    restart: unless-stopped
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:-minioadmin}
      MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:-minio_dev_password}
    command: server /data --console-address ":9001"
    volumes:
      - minio_data:/data
    networks:
      - goa-gel-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  # ================================
  # Hyperledger Besu Node
  # ================================
  besu-node-1:
    image: hyperledger/besu:24.1.0
    container_name: goa-gel-besu-1
    restart: unless-stopped
    user: root
    ports:
      - "8545:8545"
      - "8546:8546"
      - "30303:30303"
    command:
      - --network=dev
      - --miner-enabled
      - --miner-coinbase=0xfe3b557e8fb62b89f4916b721be55ceb828dbd73
      - --rpc-http-enabled
      - --rpc-http-host=0.0.0.0
      - --rpc-http-port=8545
      - --rpc-http-cors-origins=*
      - --rpc-http-api=ETH,NET,WEB3,DEBUG,MINER,ADMIN,TXPOOL,TRACE
      - --rpc-ws-enabled
      - --rpc-ws-host=0.0.0.0
      - --rpc-ws-port=8546
      - --host-allowlist=*
      - --min-gas-price=0
      - --data-path=/var/lib/besu
    volumes:
      - besu_data:/var/lib/besu
    networks:
      - goa-gel-network
    healthcheck:
      test: ["CMD-SHELL", "exit 0"]
      interval: 30s
      timeout: 10s
      retries: 3

  # ================================
  # Blockscout Database
  # ================================
  blockscout-db:
    image: postgres:15-alpine
    container_name: goa-gel-blockscout-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: blockscout
      POSTGRES_USER: blockscout
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-blockscout_dev_password}
    volumes:
      - blockscout_db_data:/var/lib/postgresql/data
    networks:
      - goa-gel-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U blockscout -d blockscout"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ================================
  # Blockscout Explorer
  # ================================
  blockscout:
    image: blockscout/blockscout:6.3.0
    container_name: goa-gel-blockscout
    restart: unless-stopped
    ports:
      - "4000:4000"
    environment:
      DATABASE_URL: postgresql://blockscout:${DATABASE_PASSWORD:-blockscout_dev_password}@blockscout-db:5432/blockscout
      ETHEREUM_JSONRPC_VARIANT: besu
      ETHEREUM_JSONRPC_HTTP_URL: http://besu-node-1:8545
      ETHEREUM_JSONRPC_WS_URL: ws://besu-node-1:8546
      ETHEREUM_JSONRPC_TRACE_URL: http://besu-node-1:8545
      NETWORK: Goa-GEL Private Network
      SUBNETWORK: Development
      LOGO: /images/blockscout_logo.svg
      LOGO_FOOTER: /images/blockscout_logo.svg
      COIN: ETH
      COIN_NAME: Ether
      INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER: "true"
      INDEXER_DISABLE_INTERNAL_TRANSACTIONS_FETCHER: "false"
      FETCH_REWARDS_WAY: trace_block
      TRACE_FIRST_BLOCK: "0"
      TRACE_LAST_BLOCK: ""
      POOL_SIZE: 80
      POOL_SIZE_API: 10
      ECTO_USE_SSL: "false"
      SECRET_KEY_BASE: ${BLOCKSCOUT_SECRET_KEY_BASE:-RMgI4C1HSkxsEjdhtGMfwAHfyT6CKWXOgzCboJflfSm4jeAlic52io05KB6mqzc5}
      PORT: 4000
      DISABLE_EXCHANGE_RATES: "true"
      SHOW_TXS_CHART: "true"
      HISTORY_FETCH_INTERVAL: 30
      TXS_HISTORIAN_INIT_LAG: 0
      TXS_STATS_DAYS_TO_COMPILE_AT_INIT: 10
      HEART_BEAT_TIMEOUT: 60
      BLOCKSCOUT_HOST: localhost
      BLOCKSCOUT_PROTOCOL: http
      API_V2_ENABLED: "true"
      MIX_ENV: prod
    depends_on:
      blockscout-db:
        condition: service_healthy
      besu-node-1:
        condition: service_healthy
    networks:
      - goa-gel-network
    command: sh -c "bin/blockscout eval \"Elixir.Explorer.ReleaseTasks.create_and_migrate()\" && bin/blockscout start"

  # ================================
  # NestJS API Backend
  # ================================
  api:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: goa-gel-api
    restart: unless-stopped
    ports:
      - "3001:3001"
    environment:
      # Application
      NODE_ENV: ${NODE_ENV:-production}
      PORT: 3001
      # CORS - set to frontend URL for remote access
      CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:4200}
      # Database (must match postgres service)
      DATABASE_HOST: postgres
      DATABASE_PORT: 5432
      DATABASE_NAME: goa_gel_platform
      DATABASE_USER: postgres
      DATABASE_PASSWORD: ${DATABASE_PASSWORD:-postgres_dev_password}
      # Redis
      REDIS_HOST: redis
      REDIS_PORT: 6379
      # MinIO (must match minio service)
      MINIO_ENDPOINT: minio
      MINIO_PORT: 9000
      MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
      MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minio_dev_password}
      MINIO_BUCKET_DOCUMENTS: goa-gel-documents
      # Blockchain
      BESU_RPC_URL: http://besu-node-1:8545
      BESU_CHAIN_ID: 1337
      BESU_NETWORK_ID: 2024
      # Smart Contracts (populated after blockchain contract deployment)
      CONTRACT_ADDRESS_LICENSE_NFT: ${CONTRACT_ADDRESS_LICENSE_NFT:-}
      CONTRACT_ADDRESS_APPROVAL_MANAGER: ${CONTRACT_ADDRESS_APPROVAL_MANAGER:-}
      CONTRACT_ADDRESS_DEPARTMENT_REGISTRY: ${CONTRACT_ADDRESS_DEPARTMENT_REGISTRY:-}
      CONTRACT_ADDRESS_WORKFLOW_REGISTRY: ${CONTRACT_ADDRESS_WORKFLOW_REGISTRY:-}
      PLATFORM_WALLET_PRIVATE_KEY: ${PLATFORM_WALLET_PRIVATE_KEY:-}
      # Security
      JWT_SECRET: ${JWT_SECRET:-dev_jwt_secret_change_in_production_min32chars}
      # Misc
      FORCE_RESEED: ${FORCE_RESEED:-false}
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
      besu-node-1:
        condition: service_healthy
    networks:
      - goa-gel-network
    volumes:
      - api_data:/app/data
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:3001/api/v1/health"]
      interval: 30s
      timeout: 10s
      start_period: 60s
      retries: 5

  # ================================
  # Angular Frontend
  # ================================
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    container_name: goa-gel-frontend
    restart: unless-stopped
    ports:
      - "4200:80"
    environment:
      # Runtime API URL - browsers need the public/external URL to reach the API
      # For local: http://localhost:3001/api/v1
      # For remote: http://<server-ip>:3001/api/v1 or https://api.yourdomain.com/api/v1
      API_BASE_URL: ${API_BASE_URL:-http://localhost:3001/api/v1}
    depends_on:
      api:
        condition: service_healthy
    networks:
      - goa-gel-network
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost/"]
      interval: 30s
      timeout: 10s
      retries: 3

  # ================================
  # Documentation Service (Optional)
  # ================================
  documentation:
    build:
      context: ./Documentation
      dockerfile: Dockerfile
    container_name: goa-gel-documentation
    restart: unless-stopped
    ports:
      - "8080:80"
    networks:
      - goa-gel-network
    profiles:
      - docs  # Only starts with: docker-compose --profile docs up
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost/"]
      interval: 30s
      timeout: 10s
      retries: 3

networks:
  goa-gel-network:
    driver: bridge

volumes:
  postgres_data:
  redis_data:
  minio_data:
  besu_data:
  blockscout_db_data:
  api_data:
