name: Blog Deployment

on:
  push:
    branches:
      - preview
  schedule:
    - cron: '0 3 * * 5'

env:
  DOCKER_IMAGE: vezpi-blog

jobs:
  Check-Rebuild:
    runs-on: docker
    defaults:
      run:
        shell: sh
    outputs:
      latest_hugo_version: ${{ steps.get_latest.outputs.version }}
      current_hugo_version: ${{ steps.get_current.outputs.version }}
      newer_version_available: ${{ steps.compare.outputs.version }}
      current_docker_image: ${{ steps.current_docker.outputs.image }}
      docker_folder_changed: ${{ steps.docker_folder.outputs.changed }}
      dev_lock_present: ${{ steps.check_dev_lock.outputs.locked }}
    steps:
      - name: Checkout Repository
        run: git clone --branch preview https://${{ secrets.REPO_TOKEN }}@git.vezpi.me/Vezpi/blog.git .

      - name: Check Latest Hugo Version
        id: get_latest
        run: |
          apk add curl
          latest_version=$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep tag_name | sed -E 's/.*"v([^"]+)".*/\1/')
          echo "version=$latest_version" | tee -a $GITEA_OUTPUT

      - name: Check Current Hugo Version
        id: get_current
        run: |
          current_version=$(docker image ls ${DOCKER_IMAGE} --format '{{.Tag}}' | head -n1)
          echo "version=$current_version" | tee -a $GITEA_OUTPUT
      
      - name: Compare Current and Latest Hugo Versions
        id: compare
        run: |
          if [ "${{ steps.get_latest.outputs.version }}" != "${{ steps.get_current.outputs.version }}" ]; then
            new_version_available=true
            echo "New version available: ${{ steps.get_latest.outputs.version }}"
          else
            new_version_available=false
            echo "Current version is the latest: ${{ steps.get_latest.outputs.version }}"
          fi
          echo "version=$new_version_available" | tee -a $GITEA_OUTPUT

      - name: Get Current Docker Image ID
        id: current_docker
        run: |
          current_image=$(docker image ls ${DOCKER_IMAGE}:latest --format '{{.ID}}' | head -n1)
          echo "image=$current_image" | tee -a $GITEA_OUTPUT

      - name: Check Changes in the Docker Folder
        id: docker_folder
        run: |
          if git diff --name-only origin/main | grep -q '^docker/'; 
          then 
            docker_folder_changed=true
            echo "Change detected in the /docker folder"
          else 
            docker_folder_changed=false
            echo "No change in the /docker folder"
          fi
          echo "changed=$docker_folder_changed" | tee -a $GITEA_OUTPUT
      
      - name: Check for .dev-lock file
        id: check_dev_lock
        run: |
          if [ -f .dev-lock ]; then
            echo "locked=true" | tee -a $GITEA_OUTPUT
          else
            echo "locked=false" | tee -a $GITEA_OUTPUT
          fi

  Build:
    needs: Check-Rebuild
    if: needs.Check-Rebuild.outputs.newer_version_available == 'true' || needs.Check-Rebuild.outputs.docker_folder_changed == 'true'
    runs-on: docker
    defaults:
      run:
        shell: sh
    steps:
      - name: Checkout Repository
        run: git clone --branch preview https://${{ secrets.REPO_TOKEN }}@git.vezpi.me/Vezpi/blog.git .

      - name: Build Docker Image
        run: |  
          cd docker
          docker build \
            --build-arg HUGO_VERSION=${{ needs.Check-Rebuild.outputs.latest_hugo_version }} \
            --tag ${DOCKER_IMAGE}:${{ needs.Check-Rebuild.outputs.latest_hugo_version }} \
            .
          docker tag ${DOCKER_IMAGE}:${{ needs.Check-Rebuild.outputs.latest_hugo_version }} ${DOCKER_IMAGE}:latest

  Deploy-Staging:
    needs: [Check-Rebuild, Build]
    if: always() && needs.Check-Rebuild.result == 'success' && (needs.Build.result == 'skipped' || needs.Build.result == 'success')
    runs-on: docker
    container:
      volumes:
        - /appli/docker/blog:/blog
    defaults:
      run:
        shell: sh
    env:
      CONTAINER_NAME: blog_staging
    steps:
      - name: Launch Blog Deployment
        run: |
          cd /blog
          docker compose down ${CONTAINER_NAME} 
          docker compose up -d ${CONTAINER_NAME}
          sleep 5
          echo "- Displaying container logs"
          docker compose logs ${CONTAINER_NAME}

  Test-Staging:
    needs: Deploy-Staging
    runs-on: ubuntu
    env:
      URL: "https://blog-dev.vezpi.com/en/"
    steps:
      - name: Check HTTP Response
        run: |
          code=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
          echo "HTTP response code: $code"

          if [ "$code" -ne 200 ]; then
            echo "❌ Service is not healthy (HTTP $code)"
            exit 1
          else
            echo "✅ Service is healthy"
          fi

  Merge:
    needs: Test-Staging
    if: needs.Test-Staging.result == 'success' && needs.Check-Rebuild.outputs.dev_lock_present == 'false'
    runs-on: ubuntu
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: main
      
      - name: Merge preview Branch on main
        run: |
          git merge --ff-only origin/preview
          git push origin main

  Deploy-Production:
    needs: Merge
    runs-on: docker
    container:
      volumes:
        - /appli/docker/blog:/blog
    defaults:
      run:
        shell: sh
    env:
      CONTAINER_NAME: blog_production
    steps:
      - name: Launch Blog Deployment
        run: |
          cd /blog
          docker compose down ${CONTAINER_NAME} 
          docker compose up -d ${CONTAINER_NAME}
          sleep 5
          echo "- Displaying container logs"
          docker compose logs ${CONTAINER_NAME}

  Test-Production:
    needs: Deploy-Production
    runs-on: ubuntu
    env:
      URL: "https://blog.vezpi.com/en/"
    steps:
      - name: Check HTTP Response
        run: |
          code=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
          echo "HTTP response code: $code"

          if [ "$code" -ne 200 ]; then
            echo "❌ Service is not healthy (HTTP $code)"
            exit 1
          else
            echo "✅ Service is healthy"
          fi

  Clean:
    needs: [Check-Rebuild, Build, Test-Production]
    runs-on: docker
    defaults:
      run:
        shell: sh
    steps:
      - name: Remove Old Docker Image
        run: |
          docker image rm ${{ needs.Check-Rebuild.outputs.current_docker_image }} --force
  
  Notify:
    needs: [Check-Rebuild, Build, Deploy-Staging, Test-Staging, Merge, Deploy-Production, Test-Production, Clean]
    runs-on: ubuntu
    if: always() && needs.Check-Rebuild.outputs.dev_lock_present == 'false'
    env:
      NTFY_URL: https://ntfy.vezpi.me
      NTFY_TOPIC: blog
      NTFY_TOKEN: ${{ secrets.NTFY_CREDENTIALS }}
    steps:
      - name: Notify Workflow Result
        run: |
          if [[
            "${{ needs.Check-Rebuild.result }}" == "success" &&
           ("${{ needs.Build.result }}" == "success" || "${{ needs.Build.result }}" == "skipped") &&
            "${{ needs.Deploy-Staging.result }}" == "success" &&
            "${{ needs.Test-Staging.result }}" == "success" && 
            "${{ needs.Merge.result }}" == "success" &&
            "${{ needs.Deploy-Production.result }}" == "success" &&
            "${{ needs.Test-Production.result }}" == "success" &&
           ("${{ needs.Clean.result }}" == "success" || "${{ needs.Clean.result }}" == "skipped")
          ]]; then
            curl -H "Priority: min" \
                 -H "Tags: white_check_mark" \
                 -d "Blog workflow completed successfully." \
                 -u ${NTFY_TOKEN} \
                 ${NTFY_URL}/${NTFY_TOPIC}
          else
            curl -H "Priority: high" \
                 -H "Tags: x" \
                 -H "Actions: view, View Run, ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_number }}, clear=true; \
                              view, Verify Blog, https://blog.vezpi.com, clear=true" \
                 -d "Blog workflow failed!" \
                 -u ${NTFY_TOKEN} \
                 ${NTFY_URL}/${NTFY_TOPIC}
          fi

          