# =============================================================================
# MPC-System Docker Compose Configuration
# =============================================================================
# Purpose: TSS (Threshold Signature Scheme) key generation and signing service
#
# Usage:
#   Development: docker compose up -d
#   Production:  docker compose --env-file .env up -d
#
# External Ports:
#   4000  - Account Service HTTP API (accessed by backend mpc-service)
#   8081  - Session Coordinator API (accessed by backend mpc-service)
#   8082  - Message Router WebSocket (accessed by backend mpc-service)
#   8083  - Server Party API (accessed by backend mpc-service for user share generation)
# =============================================================================

services:
  # ============================================
  # Infrastructure Services
  # ============================================

  # PostgreSQL Database
  postgres:
    image: postgres:15-alpine
    container_name: mpc-postgres
    environment:
      TZ: Asia/Shanghai
      POSTGRES_DB: mpc_system
      POSTGRES_USER: ${POSTGRES_USER:-mpc_user}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./migrations:/docker-entrypoint-initdb.d:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mpc_user} -d mpc_system"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # ============================================
  # MPC Core Services
  # ============================================

  # Session Coordinator Service - 会话协调器
  session-coordinator:
    build:
      context: .
      dockerfile: services/session-coordinator/Dockerfile
    container_name: mpc-session-coordinator
    ports:
      - "8081:8080"  # HTTP API for external access
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_GRPC_PORT: 50051
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
      MPC_JWT_SECRET_KEY: ${JWT_SECRET_KEY}
      MPC_JWT_ISSUER: mpc-system
      MESSAGE_ROUTER_ADDR: message-router:50051
      ACCOUNT_SERVICE_ADDR: http://account-service:8080
    depends_on:
      postgres:
        condition: service_healthy
      message-router:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # Message Router Service - 消息路由
  message-router:
    build:
      context: .
      dockerfile: services/message-router/Dockerfile
    container_name: mpc-message-router
    ports:
      - "50051:50051"  # gRPC for party connections
      - "8082:8080"    # HTTP for health checks
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_GRPC_PORT: 50051
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # ============================================
  # Server Party Services - TSS 参与方
  # 2-of-3 阈值签名: 至少 2 个 party 参与才能完成签名
  # ============================================

  # Server Party 1
  server-party-1:
    build:
      context: .
      dockerfile: services/server-party/Dockerfile
    container_name: mpc-server-party-1
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_GRPC_PORT: 50051
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
      SESSION_COORDINATOR_ADDR: session-coordinator:50051
      MESSAGE_ROUTER_ADDR: message-router:50051
      MPC_CRYPTO_MASTER_KEY: ${CRYPTO_MASTER_KEY}
      PARTY_ID: server-party-1
    depends_on:
      postgres:
        condition: service_healthy
      session-coordinator:
        condition: service_healthy
      message-router:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # Server Party 2
  server-party-2:
    build:
      context: .
      dockerfile: services/server-party/Dockerfile
    container_name: mpc-server-party-2
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_GRPC_PORT: 50051
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
      SESSION_COORDINATOR_ADDR: session-coordinator:50051
      MESSAGE_ROUTER_ADDR: message-router:50051
      MPC_CRYPTO_MASTER_KEY: ${CRYPTO_MASTER_KEY}
      PARTY_ID: server-party-2
    depends_on:
      postgres:
        condition: service_healthy
      session-coordinator:
        condition: service_healthy
      message-router:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # Server Party 3
  server-party-3:
    build:
      context: .
      dockerfile: services/server-party/Dockerfile
    container_name: mpc-server-party-3
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_GRPC_PORT: 50051
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
      SESSION_COORDINATOR_ADDR: session-coordinator:50051
      MESSAGE_ROUTER_ADDR: message-router:50051
      MPC_CRYPTO_MASTER_KEY: ${CRYPTO_MASTER_KEY}
      PARTY_ID: server-party-3
    depends_on:
      postgres:
        condition: service_healthy
      session-coordinator:
        condition: service_healthy
      message-router:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # ============================================
  # Server Party API - User Share Generation Service
  # Unlike other server-party services, this one returns shares to the caller
  # instead of storing them internally
  # ============================================
  server-party-api:
    build:
      context: .
      dockerfile: services/server-party-api/Dockerfile
    container_name: mpc-server-party-api
    ports:
      - "8083:8080"  # HTTP API for user share generation
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      SESSION_COORDINATOR_ADDR: session-coordinator:50051
      MESSAGE_ROUTER_ADDR: message-router:50051
      MPC_CRYPTO_MASTER_KEY: ${CRYPTO_MASTER_KEY}
      # API 认证密钥 (与 mpc-service 配置的 MPC_API_KEY 一致)
      MPC_API_KEY: ${MPC_API_KEY}
      # Party identity for Message Router registration
      PARTY_ID: delegate-party
      PARTY_ROLE: delegate
    depends_on:
      session-coordinator:
        condition: service_healthy
      message-router:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # ============================================
  # Co-Managed Server Party Services - TSS 参与方 (专用于 co_managed_keygen)
  # 与普通 server-party 隔离，使用两阶段事件处理
  # 行为与 service-party-app 100% 兼容
  # ============================================

  # Co-Managed Server Party 1
  server-party-co-managed-1:
    build:
      context: .
      dockerfile: services/server-party-co-managed/Dockerfile
    container_name: mpc-server-party-co-managed-1
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
      MESSAGE_ROUTER_ADDR: message-router:50051
      MPC_CRYPTO_MASTER_KEY: ${CRYPTO_MASTER_KEY}
      PARTY_ID: co-managed-party-1
    depends_on:
      postgres:
        condition: service_healthy
      session-coordinator:
        condition: service_healthy
      message-router:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # Co-Managed Server Party 2
  server-party-co-managed-2:
    build:
      context: .
      dockerfile: services/server-party-co-managed/Dockerfile
    container_name: mpc-server-party-co-managed-2
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
      MESSAGE_ROUTER_ADDR: message-router:50051
      MPC_CRYPTO_MASTER_KEY: ${CRYPTO_MASTER_KEY}
      PARTY_ID: co-managed-party-2
    depends_on:
      postgres:
        condition: service_healthy
      session-coordinator:
        condition: service_healthy
      message-router:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # Co-Managed Server Party 3
  server-party-co-managed-3:
    build:
      context: .
      dockerfile: services/server-party-co-managed/Dockerfile
    container_name: mpc-server-party-co-managed-3
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
      MESSAGE_ROUTER_ADDR: message-router:50051
      MPC_CRYPTO_MASTER_KEY: ${CRYPTO_MASTER_KEY}
      PARTY_ID: co-managed-party-3
    depends_on:
      postgres:
        condition: service_healthy
      session-coordinator:
        condition: service_healthy
      message-router:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

  # ============================================
  # Account Service - External API Entry Point
  # Main HTTP API for backend mpc-service integration
  # ============================================
  account-service:
    build:
      context: .
      dockerfile: services/account/Dockerfile
    container_name: mpc-account-service
    ports:
      - "4000:8080"  # HTTP API for external access
    environment:
      TZ: Asia/Shanghai
      MPC_SERVER_GRPC_PORT: 50051
      MPC_SERVER_HTTP_PORT: 8080
      MPC_SERVER_ENVIRONMENT: ${ENVIRONMENT:-development}
      MPC_LOGGER_LEVEL: ${LOG_LEVEL:-debug}
      MPC_DATABASE_HOST: postgres
      MPC_DATABASE_PORT: 5432
      MPC_DATABASE_USER: ${POSTGRES_USER:-mpc_user}
      MPC_DATABASE_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
      MPC_DATABASE_DBNAME: mpc_system
      MPC_DATABASE_SSLMODE: disable
      MPC_COORDINATOR_URL: session-coordinator:50051
      MPC_JWT_SECRET_KEY: ${JWT_SECRET_KEY}
      # API 认证密钥 (与 mpc-service 配置的 MPC_API_KEY 一致)
      MPC_API_KEY: ${MPC_API_KEY}
      # Allowed source IPs (backend servers)
      # Empty default = allow all (protected by API_KEY). Set in .env for production!
      ALLOWED_IPS: ${ALLOWED_IPS:-}
    depends_on:
      postgres:
        condition: service_healthy
      session-coordinator:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - mpc-network
    restart: unless-stopped

# ============================================
# Networks
# ============================================
networks:
  mpc-network:
    driver: bridge

# ============================================
# Volumes - 持久化存储
# ============================================
volumes:
  postgres-data:
    driver: local
