services:
  rag-api:
    build:
      context: ..
      dockerfile: Apis/rag-api/Dockerfile
    container_name: myai-rag-api
    ports:
      - "8081:8080"
    env_file:
      - .env
    environment:
      # ASP.NET
      - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
      - ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
      - APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
      - LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}

      # Database: matches rag-api appsettings Database section
      - Database__Host=${Database__Host:-sqlserver}
      - Database__Port=${Database__Port:-1433}
      - Database__Name=${Database__Name:-MyAiDb}
      - Database__User=${Database__User:-sa}
      - Database__Password=${Database__Password:-}
      - Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}

      # InternalApi: matches rag-api appsettings InternalApi section
      - InternalApi__ApiKey=${RagApi__InternalApiKey:-change-this-internal-key}
      - InternalApi__RequireApiKey=${RagApi__RequireApiKey:-false}

      # Rag: matches rag-api appsettings Rag section
      - Rag__MaxFileSizeMb=${Rag__MaxFileSizeMb:-8}
      - Rag__ChunkSize=${Rag__ChunkSize:-900}
      - Rag__ChunkOverlap=${Rag__ChunkOverlap:-150}
      - Rag__MaxTextChars=${Rag__MaxTextChars:-60000}
      - Rag__DefaultTopK=${Rag__DefaultTopK:-20}
      - Rag__MaxTopK=${Rag__MaxTopK:-50}
      - Rag__ClassifyWithAi=${Rag__ClassifyWithAi:-false}

      # Ai: matches rag-api appsettings Ai section
      - Ai__Provider=${Ai__Provider:-OpenAI}
      - Ai__OpenAI__ApiKey=${Ai__OpenAI__ApiKey:-}
      - Ai__OpenAI__ChatModel=${Ai__OpenAI__ChatModel:-gpt-4o-mini}
      - Ai__OpenAI__EmbeddingModel=${Ai__OpenAI__EmbeddingModel:-text-embedding-3-small}
      - Ai__OpenAI__TimeoutSeconds=${Ai__OpenAI__TimeoutSeconds:-90}
      - Ai__Ollama__BaseUrl=${Ai__Ollama__BaseUrl:-http://host.docker.internal:11434}
      - Ai__Ollama__ChatModel=${Ai__Ollama__ChatModel:-llama3.1:8b}
      - Ai__Ollama__EmbeddingModel=${Ai__Ollama__EmbeddingModel:-nomic-embed-text}
      - Ai__Ollama__TimeoutSeconds=${Ai__Ollama__TimeoutSeconds:-180}

      # Logging / Serilog
      - Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
      - Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
      - Logging__LogLevel__Microsoft__AspNetCore=${Logging__LogLevel__Microsoft__AspNetCore:-Warning}
      - Logging__LogLevel__Api=${Logging__LogLevel__Api:-Information}
      - Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
      - Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
      - Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
      - Serilog__WriteTo__2__Args__networkCredential__userName=${Serilog__WriteTo__2__Args__networkCredential__userName:-}
      - Serilog__WriteTo__2__Args__networkCredential__password=${Serilog__WriteTo__2__Args__networkCredential__password:-}
      - Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
      - Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
    volumes:
      - ../Apis/api/logs:/app/logs
      - ../Apis/api/Files:/app/Files
    networks:
      - myai-network
    restart: unless-stopped
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

  cv-matcher-api:
    build:
      context: ..
      dockerfile: Apis/cv-matcher-api/Dockerfile
    container_name: myai-cv-matcher-api
    depends_on:
      - rag-api
    ports:
      - "8082:8080"
    env_file:
      - .env
    environment:
      # ASP.NET
      - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
      - ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
      - APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
      - LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}

      # Database: matches cv-matcher-api appsettings Database section
      - Database__Host=${Database__Host:-sqlserver}
      - Database__Port=${Database__Port:-1433}
      - Database__Name=${Database__Name:-MyAiDb}
      - Database__User=${Database__User:-sa}
      - Database__Password=${Database__Password:-}
      - Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}

      # InternalApi: matches cv-matcher-api appsettings InternalApi section
      - InternalApi__ApiKey=${CvMatcherApi__InternalApiKey:-change-this-internal-key}
      - InternalApi__RequireApiKey=${CvMatcherApi__RequireApiKey:-false}

      # RagApi: matches cv-matcher-api appsettings RagApi section
      - RagApi__BaseUrl=${RagApi__BaseUrl:-http://rag-api:8080}
      - RagApi__InternalApiKey=${RagApi__InternalApiKey:-change-this-internal-key}

      # Ai: matches cv-matcher-api appsettings Ai section
      - Ai__Provider=${Ai__Provider:-OpenAI}
      - Ai__OpenAI__ApiKey=${Ai__OpenAI__ApiKey:-}
      - Ai__OpenAI__ChatModel=${Ai__OpenAI__ChatModel:-gpt-4o-mini}
      - Ai__OpenAI__TimeoutSeconds=${Ai__OpenAI__TimeoutSeconds:-90}
      - Ai__Ollama__BaseUrl=${Ai__Ollama__BaseUrl:-http://host.docker.internal:11434}
      - Ai__Ollama__ChatModel=${Ai__Ollama__ChatModel:-llama3.1:8b}
      - Ai__Ollama__TimeoutSeconds=${Ai__Ollama__TimeoutSeconds:-180}

      # Matcher: matches cv-matcher-api appsettings Matcher section
      - Matcher__TopK=${Matcher__TopK:-10}
      - Matcher__DeepScoreTopN=${Matcher__DeepScoreTopN:-5}
      - Matcher__MaxJobTextChars=${Matcher__MaxJobTextChars:-60000}

      # Logging / Serilog
      - Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
      - Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
      - Logging__LogLevel__Microsoft__AspNetCore=${Logging__LogLevel__Microsoft__AspNetCore:-Warning}
      - Logging__LogLevel__Api=${Logging__LogLevel__Api:-Information}
      - Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
      - Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
      - Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
      - Serilog__WriteTo__2__Args__networkCredential__userName=${Serilog__WriteTo__2__Args__networkCredential__userName:-}
      - Serilog__WriteTo__2__Args__networkCredential__password=${Serilog__WriteTo__2__Args__networkCredential__password:-}
      - Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
      - Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
    volumes:
      - ../Apis/api/logs:/app/logs      
    networks:
      - myai-network
    restart: unless-stopped
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

  api:
    build:
      context: ..
      dockerfile: Apis/api/Dockerfile
    container_name: myai-api
    depends_on:
      - cv-matcher-api
    ports:
      - "8080:8080"
    env_file:
      - .env
      # Keep this only if Apis/api/.env contains api-specific overrides not present in docker-compose/.env.
      # - ../Apis/api/.env
    environment:
      # ASP.NET
      - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
      - ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
      - APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
      - LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}

      # Google: matches api appsettings Google section
      - Google__TagManagerId=${Google__TagManagerId:-}
      - Google__MapKey=${Google__MapKey:-}

      # Contact / Subscribe: matches api appsettings Contact and Subscribe sections
      - Contact__ToEmail=${Contact__ToEmail:-}
      - Contact__FromEmail=${Contact__FromEmail:-${Smtp__Username:-}}
      - Contact__SubjectPrefix=${Contact__SubjectPrefix:-}
      - Subscribe__ToEmail=${Subscribe__ToEmail:-}
      - Subscribe__SubjectPrefix=${Subscribe__SubjectPrefix:-}

      # SMTP: matches api appsettings Smtp section
      - Smtp__Host=${Smtp__Host:-mail.example.com}
      - Smtp__Port=${Smtp__Port:-587}
      - Smtp__Username=${Smtp__Username:-}
      - Smtp__Password=${Smtp__Password:-}
      - Smtp__UseStartTls=${Smtp__UseStartTls:-false}

      # Captcha: matches api appsettings Captcha section
      - Captcha__Provider=${Captcha__Provider:-Recaptcha}
      - Captcha__SecretKey=${Captcha__SecretKey:-}
      - Captcha__PublicKey=${Captcha__PublicKey:-}
      - Captcha__MinimumScore=${Captcha__MinimumScore:-0.5}

      # FileStorage: matches api appsettings FileStorage section
      - FileStorage__Path=${FileStorage__Path:-Files}
      - FileStorage__DefaultFileName=${FileStorage__DefaultFileName:-}
      - FileStorage__ToEmail=${FileStorage__ToEmail:-}
      - FileStorage__FromEmail=${FileStorage__FromEmail:-${Smtp__Username:-}}
      - FileStorage__SubjectPrefix=${FileStorage__SubjectPrefix:-[File Download]}

      # CvMatcherApi: matches api appsettings CvMatcherApi section
      - CvMatcherApi__BaseUrl=${CvMatcherApi__BaseUrl:-http://cv-matcher-api:8080}
      - CvMatcherApi__InternalApiKey=${CvMatcherApi__InternalApiKey:-change-this-internal-key}

      # JobSearch: base URL used to build the job search link in match emails
      - JobSearch__BaseUrl=${JobSearch__JobSearchLinkBaseUrl:-https://myai.ro}

      # Rate Limiting: matches api appsettings RateLimiting section
      - RateLimiting__Global__PermitLimit=${RateLimiting__Global__PermitLimit:-120}
      - RateLimiting__Global__Window=${RateLimiting__Global__Window:-00:01:00}
      - RateLimiting__Global__QueueLimit=${RateLimiting__Global__QueueLimit:-0}
      - RateLimiting__Policies__contact__PermitLimit=${RateLimiting__Policies__contact__PermitLimit:-5}
      - RateLimiting__Policies__contact__Window=${RateLimiting__Policies__contact__Window:-00:01:00}
      - RateLimiting__Policies__contact__QueueLimit=${RateLimiting__Policies__contact__QueueLimit:-0}
      - RateLimiting__Policies__cvMatcher__PermitLimit=${RateLimiting__Policies__cvMatcher__PermitLimit:-10}
      - RateLimiting__Policies__cvMatcher__Window=${RateLimiting__Policies__cvMatcher__Window:-00:10:00}
      - RateLimiting__Policies__cvMatcher__QueueLimit=${RateLimiting__Policies__cvMatcher__QueueLimit:-0}

      # CORS: not in the uploaded api appsettings, but used by your API startup config.
      - Cors__AllowedOrigins__0=${Cors__AllowedOrigins__0:-http://localhost:5000}
      - Cors__AllowedOrigins__1=${Cors__AllowedOrigins__1:-http://web:8080}

      # Logging / Serilog
      - Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
      - Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
      - Logging__LogLevel__Microsoft__AspNetCore=${Logging__LogLevel__Microsoft__AspNetCore:-Warning}
      - Logging__LogLevel__Api=${Logging__LogLevel__Api:-Information}
      - Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
      - Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
      - Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
      - Serilog__WriteTo__2__Args__networkCredential__userName=${Serilog__WriteTo__2__Args__networkCredential__userName:-}
      - Serilog__WriteTo__2__Args__networkCredential__password=${Serilog__WriteTo__2__Args__networkCredential__password:-}
      - Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
      - Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
    volumes:
      - ../Apis/api/logs:/app/logs
      - ../Apis/api/Files:/app/Files
    networks:
      - myai-network
    restart: unless-stopped
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

  cv-cleanup-job:
    build:
      context: ..
      dockerfile: Jobs/cv-cleanup-job/Dockerfile
    container_name: myai-cv-cleanup-job
    depends_on:
      - api
    env_file:
      - .env
    environment:
      # Worker + diagnostics (matches Jobs/cv-cleanup-job appsettings)
      - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
      - APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
      - LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}

      # FileStorage: matches cv-cleanup-job appsettings FileStorage section
      - FileStorage__Path=${FileStorage__Path:-Files}

      # Jobs: matches cv-cleanup-job appsettings Jobs:Tasks
      - Jobs__Tasks__0__Enabled=${Jobs__CvStorageCleanupEnabled:-true}
      - Jobs__Tasks__0__Interval=${Jobs__CvStorageCleanupInterval:-01:00:00}
      - Jobs__Tasks__0__Parameters__MaxTotalSizeMegabytes=${Jobs__CvStorageMaxTotalSizeMegabytes:-40}

      # Logging / Serilog (matches Jobs/cv-cleanup-job appsettings Serilog section; WriteTo index 2 = Email)
      - Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
      - Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
      - Logging__LogLevel__Microsoft__Hosting__Lifetime=${Logging__LogLevel__Microsoft__Hosting__Lifetime:-Information}
      - Logging__LogLevel__CvCleanupJob=${Logging__LogLevel__CvCleanupJob:-Information}
      - Logging__LogLevel__JobScheduler=${Logging__LogLevel__JobScheduler:-Information}
      - Serilog__MinimumLevel__Override__CvCleanupJob=${Serilog__MinimumLevel__Override__CvCleanupJob:-Information}
      - Serilog__MinimumLevel__Override__JobScheduler=${Serilog__MinimumLevel__Override__JobScheduler:-Information}
      - Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
      - Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
      - Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
      - Serilog__WriteTo__2__Args__networkCredential__userName=${Serilog__WriteTo__2__Args__networkCredential__userName:-}
      - Serilog__WriteTo__2__Args__networkCredential__password=${Serilog__WriteTo__2__Args__networkCredential__password:-}
      - Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
      - Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
    volumes:
      - ../Jobs/cv-cleanup-job/logs:/app/logs
      - ../Apis/api/Files:/app/Files
    networks:
      - myai-network
    restart: unless-stopped
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

  cv-search-job:
    build:
      context: ..
      dockerfile: Jobs/cv-search-job/Dockerfile
    container_name: myai-cv-search-job
    depends_on:
      - cv-matcher-api
    env_file:
      - .env
    environment:
      # Worker + diagnostics
      - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
      - APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
      - LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}

      # Database
      - Database__Host=${Database__Host:-sqlserver}
      - Database__Port=${Database__Port:-1433}
      - Database__Name=${Database__Name:-MyAiDb}
      - Database__User=${Database__User:-sa}
      - Database__Password=${Database__Password:-}
      - Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}

      # CvMatcherApi (internal)
      - CvMatcherApi__BaseUrl=${CvMatcherApi__BaseUrl:-http://cv-matcher-api:8080}
      - CvMatcherApi__InternalApiKey=${CvMatcherApi__InternalApiKey:-change-this-internal-key}

      # SMTP
      - Smtp__Host=${Smtp__Host:-}
      - Smtp__Port=${Smtp__Port:-587}
      - Smtp__Username=${Smtp__Username:-}
      - Smtp__Password=${Smtp__Password:-}
      - Smtp__UseStartTls=${Smtp__UseStartTls:-false}

      # Contact
      - Contact__ToEmail=${Contact__ToEmail:-}

      # FileStorage (shared volume path must match api container)
      - FileStorage__Path=${FileStorage__Path:-Files}

      # JobSearch settings
      - JobSearch__Enabled=${JobSearch__Enabled:-true}
      - JobSearch__JobSearchLinkBaseUrl=${JobSearch__JobSearchLinkBaseUrl:-https://myai.ro}
      - JobSearch__TokenExpiryDays=${JobSearch__TokenExpiryDays:-7}
      - JobSearch__MinMatchScore=${JobSearch__MinMatchScore:-15}
      - JobSearch__MaxJobsToMatch=${JobSearch__MaxJobsToMatch:-15}

      # Job task schedule
      - Jobs__Tasks__0__TaskType=CvSearch
      - Jobs__Tasks__0__Enabled=${Jobs__CvSearchEnabled:-true}
      - Jobs__Tasks__0__Interval=${Jobs__CvSearchInterval:-00:00:30}

      # Logging / Serilog
      - Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
      - Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
      - Logging__LogLevel__Microsoft__Hosting__Lifetime=${Logging__LogLevel__Microsoft__Hosting__Lifetime:-Information}
      - Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
      - Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
      - Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
      - Serilog__WriteTo__2__Args__networkCredential__userName=${Serilog__WriteTo__2__Args__networkCredential__userName:-}
      - Serilog__WriteTo__2__Args__networkCredential__password=${Serilog__WriteTo__2__Args__networkCredential__password:-}
      - Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
      - Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
    volumes:
      - ../Jobs/cv-search-job/logs:/app/logs
      - ../Apis/api/Files:/app/Files
    networks:
      - myai-network
    restart: unless-stopped
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

  web:
    build:
      context: ..
      dockerfile: web/Dockerfile
    container_name: myai-web
    depends_on:
      - api
    ports:
      - "5000:8080"
    env_file:
      - .env
    environment:
      - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
      - ASPNETCORE_URLS=${ASPNETCORE_URLS:-http://+:8080}
      - APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}

      # Site: matches web appsettings Site section (Normal, UnderConstruction, Unavailable)
      - Site__Mode=${Site__Mode:-Normal}
    networks:
      - myai-network
    restart: unless-stopped

networks:
  myai-network:
    driver: bridge
