name: Deploy Staging

on:
  workflow_dispatch:
    inputs:
      environment:
        description: Environment to deploy to
        required: true
        default: staging
      version:
        description: Version to deploy (default is new, to see other versions use the 'Get available versions' workflow)
        required: false
        default: new
      logLevel:
        description: Log level
        required: false
        default: info
        type: choice
        options:
          - info
          - debug
          - warning

jobs:
  deploy_to_staging:
    name: Deploy to Staging
    runs-on: ubuntu-22.04

    env:
      STACK_NAME: molvaapp-${{ inputs.environment }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Extract Git metadata
        id: git-metadata
        env:
          REPO: ${{ github.repository }}
        run: |
          VERSION=${{ inputs.version }}

          if [ ${VERSION} == "new" ]; then
            GIT_SHA=$(git rev-parse --short HEAD)
            GIT_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo 'none')
          else
            GIT_SHA=$(echo ${VERSION} | cut -d'-' -f2)
            GIT_TAG='none'
          fi

          echo "VERSION=${VERSION}"
          echo "GIT_SHA=${GIT_SHA}"
          echo "GIT_TAG=${GIT_TAG}"

          echo "GIT_SHA=${GIT_SHA}" >> $GITHUB_OUTPUT
          echo "GIT_TAG=${GIT_TAG}" >> $GITHUB_OUTPUT
          echo "APP_COMMIT=$($GIT_TAG != 'none' && $GIT_TAG || $GIT_SHA)" >> $GITHUB_OUTPUT
          echo "REPO_OWNER=$(echo $REPO | cut -d'/' -f1)" >> $GITHUB_OUTPUT
          echo "REPO_NAME=$(echo $REPO | cut -d'/' -f2)" >> $GITHUB_OUTPUT

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

      - name: Extract image metadata
        id: docker-metadata
        needs: git-metadata
        env:
          REGISTRY: hub.docker.com
          REPO_NAME: ${{ steps.git-metadata.outputs.REPO_NAME }}
        run: |
          TARGET_TAG=${{ inputs.version }}

          if [ ${TARGET_TAG} == "new" ]; then
            PUSH_DATE=$(date +"%Y-%m-%d %T %Z")
            IMAGE_TAG=${{ inputs.environment }}-${{ steps.git-metadata.outputs.GIT_TAG != 'none' && steps.git-metadata.outputs.GIT_TAG || steps.git-metadata.outputs.GIT_SHA }}
          else
            PUSH_DATE=$(wget -q -O - "https://$REGISTRY/v2/namespaces/molvaapp/repositories/$REPO_NAME/tags/${TARGET_TAG}/" | jq -r '.tag_last_pushed')
            IMAGE_TAG=${{ inputs.version }}
          fi

          echo "IMAGE_NAME=molvaapp/${{ steps.git-metadata.outputs.REPO_NAME }}" >> $GITHUB_OUTPUT
          echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_OUTPUT
          echo "TAG_LAST_PUSHED=${PUSH_DATE}" >> $GITHUB_OUTPUT

      - name: Build and Push Docker Image
        if: ${{ inputs.version == 'new' }}
        needs: docker-metadata
        env:
          IMAGE_NAME: ${{ steps.docker-metadata.outputs.IMAGE_NAME }}
          IMAGE_TAG: ${{ steps.docker-metadata.outputs.IMAGE_TAG }}
          CONFIG_FILE: .build/config/staging.yaml
        run: |
          docker build \
            --build-arg BUILD_LDFLAGS="-w -s" \
            --build-arg CONFIG_FILE_PATH=$CONFIG_FILE \
            -t $IMAGE_NAME:$IMAGE_TAG \
            -t $IMAGE_NAME:latest \
            .

          docker tag $IMAGE_NAME:$IMAGE_TAG $IMAGE_NAME:latest

          docker push $IMAGE_NAME:$IMAGE_TAG
          docker push $IMAGE_NAME:latest

          echo "Pushed image $IMAGE_NAME:$IMAGE_TAG and :latest"

      - name: Install dependencies
        id: install-dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y gettext jq

      - name: Prepare environment
        id: prepare-env
        run: |
          mkdir -p /tmp/swarm-certs
          echo "${{ secrets.SWARM_CA_PEM }}" > /tmp/swarm-certs/ca.pem
          echo "${{ secrets.SWARM_CERT_PEM }}" > /tmp/swarm-certs/cert.pem
          echo "${{ secrets.SWARM_KEY_PEM }}" > /tmp/swarm-certs/key.pem
          chmod 600 /tmp/swarm-certs/*.pem

      - name: Deploy to Swarm
        needs:
          - git-metadata
          - docker-metadata
          - install-dependencies
          - prepare-env
        env:
          DOCKER_HOST: tcp://${{ secrets.SWARM_MANAGER_HOST }}:2376
          DOCKER_TLS_VERIFY: 1
          DOCKER_CERT_PATH: /tmp/swarm-certs

          VERSION: ${{ inputs.version == 'new' && 'latest' || inputs.version }}

          APP_VERSION: ${{ inputs.environment }}-${{ steps.git-metadata.outputs.APP_COMMIT }}
          APP_COMMIT: ${{ steps.git-metadata.outputs.APP_COMMIT }}
          APP_BUILD_DATE: ${{ steps.docker-metadata.outputs.TAG_LAST_PUSHED }}

          KEYCLOAK_BASE_URL: ${{ secrets.KEYCLOAK_BASE_URL }}
          KEYCLOAK_REALM: ${{ secrets.KEYCLOAK_REALM }}
          KEYCLOAK_CLIENT_ID: ${{ secrets.KEYCLOAK_CLIENT_ID }}
          KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }}

          BROKER_HOST: ${{ secrets.BROKER_HOST }}
          BROKER_PORT: ${{ secrets.BROKER_PORT }}
          BROKER_USERNAME: ${{ secrets.BROKER_USERNAME }}
          BROKER_PASSWORD: ${{ secrets.BROKER_PASSWORD }}

          SHORTENER_SECRET_KEY: ${{ secrets.SHORTENER_SECRET_KEY }}

          CACHE_ADDRS: ${{ secrets.CACHE_ADDRS }}
          CACHE_PASSWORD: ${{ secrets.CACHE_PASSWORD }}

          DB_HOSTS: ${{ secrets.DB_HOSTS }}
          DB_PORT: ${{ secrets.DB_PORT }}
          DB_USERNAME: ${{ secrets.DB_STG_USERNAME }}
          DB_PASSWORD: ${{ secrets.DB_STG_PASSWORD }}
          DB_DBNAME: ${{ secrets.DB_DBNAME }}

          INTEGRATION_VKUSVILL_API_TOKEN: ${{ secrets.INTEGRATION_VKUSVILL_API_TOKEN }}
        run: |
          envsubst < docker-compose.staging.yaml > docker-compose.runtime.yaml

          echo "Deploying version $VERSION to ${{ inputs.environment }}..."
          echo "Log level: ${{ inputs.logLevel }}"

          docker stack deploy \
            --with-registry-auth \
            -c docker-compose.runtime.yaml \
            ${{ env.STACK_NAME }}

      - name: Cleanup
        run: |
          rm -rf /tmp/swarm-certs
          rm -f docker-compose.runtime.yaml

      - name: Post-deploy
        run: |
          echo "Deployment to ${{ inputs.environment }} completed."
          echo "Version deployed: ${{ inputs.version }}"
