# EN: Build and push Docker images for all MVP services
# VI: Build va push Docker images cho tat ca MVP services
name: Docker Build

on:
  push:
    branches:
      - main
      - develop
    paths:
      - 'services/iam-service-net/**'
      - 'services/merchant-service-net/**'
      - 'services/order-service-net/**'
      - 'services/fnb-engine-net/**'
      - 'services/inventory-service-net/**'
      - 'services/wallet-service-net/**'
      - 'services/catalog-service-net/**'
      - 'services/storage-service-net/**'
      - 'apps/web-client-tpos-net/**'
  workflow_dispatch:
    inputs:
      service:
        description: 'Service to build (leave empty for changed only)'
        required: false
        default: ''

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Detect changed services
        id: set-matrix
        run: |
          if [ -n "${{ github.event.inputs.service }}" ]; then
            echo 'matrix={"include":[{"service":"${{ github.event.inputs.service }}"}]}' >> $GITHUB_OUTPUT
            exit 0
          fi

          CHANGED=$(git diff --name-only HEAD~1 HEAD)
          INCLUDES=()

          declare -A SERVICES=(
            ["services/iam-service-net"]='{"service":"iam-service-net","context":"./services/iam-service-net","image":"goodgo/iam-service-net"}'
            ["services/merchant-service-net"]='{"service":"merchant-service-net","context":"./services/merchant-service-net","image":"goodgo/merchant-service-net"}'
            ["services/order-service-net"]='{"service":"order-service-net","context":"./services/order-service-net","image":"goodgo/order-service-net"}'
            ["services/fnb-engine-net"]='{"service":"fnb-engine-net","context":"./services/fnb-engine-net","image":"goodgo/fnb-engine-net"}'
            ["services/inventory-service-net"]='{"service":"inventory-service-net","context":"./services/inventory-service-net","image":"goodgo/inventory-service-net"}'
            ["services/wallet-service-net"]='{"service":"wallet-service-net","context":"./services/wallet-service-net","image":"goodgo/wallet-service-net"}'
            ["services/catalog-service-net"]='{"service":"catalog-service-net","context":"./services/catalog-service-net","image":"goodgo/catalog-service-net"}'
            ["services/storage-service-net"]='{"service":"storage-service-net","context":"./services/storage-service-net","image":"goodgo/storage-service-net"}'
            ["apps/web-client-tpos-net"]='{"service":"web-client-tpos-net","context":"./apps/web-client-tpos-net","image":"goodgo/web-client-tpos-net"}'
          )

          for path in "${!SERVICES[@]}"; do
            if echo "$CHANGED" | grep -q "^${path}/"; then
              INCLUDES+=("${SERVICES[$path]}")
            fi
          done

          if [ ${#INCLUDES[@]} -eq 0 ]; then
            echo 'matrix={"include":[]}' >> $GITHUB_OUTPUT
          else
            JOINED=$(IFS=,; echo "${INCLUDES[*]}")
            echo "matrix={\"include\":[${JOINED}]}" >> $GITHUB_OUTPUT
          fi

  build:
    needs: detect-changes
    if: needs.detect-changes.outputs.matrix != '{"include":[]}'
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix: ${{ fromJSON(needs.detect-changes.outputs.matrix) }}
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Set tags
        id: tags
        run: |
          IMAGE="${{ matrix.image }}"
          SHA="${{ github.sha }}"
          BRANCH="${{ github.ref_name }}"

          # EN: Never push :latest — use commit SHA only for main, :staging for develop
          # VI: Khong bao gio push :latest — chi dung commit SHA cho main, :staging cho develop
          if [ "$BRANCH" = "main" ]; then
            echo "tags=${IMAGE}:${SHA}" >> $GITHUB_OUTPUT
          else
            echo "tags=${IMAGE}:staging,${IMAGE}:${SHA}" >> $GITHUB_OUTPUT
          fi

      - name: Build and push ${{ matrix.service }}
        uses: docker/build-push-action@v5
        with:
          context: ${{ matrix.context }}
          push: true
          tags: ${{ steps.tags.outputs.tags }}
          cache-from: type=registry,ref=${{ matrix.image }}:buildcache
          cache-to: type=registry,ref=${{ matrix.image }}:buildcache,mode=max

      # EN: Scan image for vulnerabilities with Trivy (DEVOPS-M-01)
      # VI: Quet lo hong bao mat image bang Trivy (DEVOPS-M-01)
      - name: Scan ${{ matrix.service }} image for vulnerabilities
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: ${{ matrix.image }}:${{ github.sha }}
          format: 'sarif'
          output: 'trivy-results-${{ matrix.service }}.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
          ignore-unfixed: true

      - name: Upload Trivy scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results-${{ matrix.service }}.sarif'
          category: 'trivy-${{ matrix.service }}'
