name: Feature Branch Workflow

on:
  delete:
    branches:
      - 'feature/*'
  push:
    branches:
      - 'feature/*'

jobs:
  setup_and_deploy:
    runs-on: ubuntu-latest
    outputs:
      BRANCH_NAME: ${{ steps.set_branch_name.outputs.BRANCH_NAME }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set branch name
        id: set_branch_name
        run: |
          if [ "${GITHUB_EVENT_NAME}" = "delete" ]; then
            GIT_BRANCH_NAME=$(jq --raw-output .ref $GITHUB_EVENT_PATH | sed 's#refs/heads/feature/##g' | sed 's/\//_/g')
            echo "GIT_BRANCH_NAME=$GIT_BRANCH_NAME" >> $GITHUB_ENV

            GIT_BRANCH_NAME=${GIT_BRANCH_NAME#feature_}
            echo "GIT_BRANCH_NAME=$GIT_BRANCH_NAME" >> $GITHUB_ENV
          else
            GIT_BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/feature/} | sed 's/\//_/g')
            echo "GIT_BRANCH_NAME=$GIT_BRANCH_NAME" >> $GITHUB_ENV
          fi
          BRANCH_NAME=$(echo "$GIT_BRANCH_NAME" | sed 's/_/-/g')
          DB_BRANCH_NAME=$(echo "$GIT_BRANCH_NAME" | sed 's/-/_/g')
          echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
          echo "DB_BRANCH_NAME=$DB_BRANCH_NAME" >> $GITHUB_ENV
          echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT

      - name: Setup SSH
        uses: webfactory/ssh-agent@v0.8.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Extract major version from Laravel version
        run: |
          LARAVEL_VERSION=$(cat composer.json | jq -r '.require."laravel/framework"')
          echo "LARAVEL_VERSION=$LARAVEL_VERSION" >> $GITHUB_ENV
          LARAVEL_MAJOR_VERSION=$(echo "$LARAVEL_VERSION" | sed 's/[^0-9]*\([0-9]\+\).*/\1/')
          echo "LARAVEL_MAJOR_VERSION=$LARAVEL_MAJOR_VERSION" >> $GITHUB_ENV

      - name: Choose Docker image based on Laravel major version
        run: |
          if [[ $LARAVEL_MAJOR_VERSION -eq 10 ]]; then
            echo "DOCKER_IMAGE=wrb:v2.0" >> $GITHUB_ENV
          else
            echo "DOCKER_IMAGE=wrb:v1.0" >> $GITHUB_ENV
          fi

      - name: Check if Docker container exists
        run: |
          EXISTS=$(ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} 'docker ps -a --filter "name=^/wrb-${{ env.BRANCH_NAME }}$" --format "{{.Names}}"')
          if [ -z "$EXISTS" ]; then
            echo "CONTAINER_EXISTS=false" >> $GITHUB_ENV
          else
            echo "CONTAINER_EXISTS=true" >> $GITHUB_ENV
            CURRENT_IMAGE=$(ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} "docker inspect --format='{{.Config.Image}}' wrb-${{ env.BRANCH_NAME }}")
            echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV
          fi

      - name: Duplicate database
        if: github.event_name == 'push' && env.CONTAINER_EXISTS == 'false'
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          mysql -e 'CREATE DATABASE feature_${{ env.DB_BRANCH_NAME }};'
          mysqldump preprod_wrb | mysql feature_${{ env.DB_BRANCH_NAME }}
          EOF

      - name: Prepare Docker volume
        if: github.event_name == 'push' && env.CONTAINER_EXISTS == 'false'
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          mkdir -p /home/ubuntu/features/${{ env.BRANCH_NAME }}
          git clone git@github.com:${{ github.repository }}.git -b feature/${{ env.GIT_BRANCH_NAME }} /home/ubuntu/features/${{ env.BRANCH_NAME }}
          cp /home/ubuntu/features/.default-feature-env /home/ubuntu/features/${{ env.BRANCH_NAME }}/.env
          sed -i 's/DB_DATABASE=preprod_wrb/DB_DATABASE=feature_${{ env.DB_BRANCH_NAME }}/g' /home/ubuntu/features/${{ env.BRANCH_NAME }}/.env
          sed -i 's|APP_URL=https://preprod.werankbox.com|APP_URL=https://${{ env.BRANCH_NAME }}.feature.werankbox.com|g' /home/ubuntu/features/${{ env.BRANCH_NAME }}/.env
          EOF

      - name: Update Docker volume
        if: github.event_name == 'push' && env.CONTAINER_EXISTS == 'true'
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          sudo chown -R ubuntu:ubuntu /home/ubuntu/features/${{ env.BRANCH_NAME }}
          cd /home/ubuntu/features/${{ env.BRANCH_NAME }}
          git pull
          EOF

      - name: Update Docker container image if necessary
        if: env.CONTAINER_EXISTS == 'true' && env.CURRENT_IMAGE != env.DOCKER_IMAGE
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          docker stop wrb-${{ env.BRANCH_NAME }}
          docker rm wrb-${{ env.BRANCH_NAME }}
          EOF
          echo "CONTAINER_EXISTS=false" >> $GITHUB_ENV

      - name: Start Docker container
        if: github.event_name == 'push' && env.CONTAINER_EXISTS == 'false'
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<'EOF'
          docker run -d \
            --name wrb-${{ env.BRANCH_NAME }} \
            --restart unless-stopped \
            --network web \
            --label "traefik.enable=true" \
            --label "traefik.http.routers.wrb-${{ env.BRANCH_NAME }}.rule=Host(\`${{ env.BRANCH_NAME }}.feature.werankbox.com\`)" \
            --label "traefik.http.routers.wrb-${{ env.BRANCH_NAME }}.entrypoints=websecure" \
            --label "traefik.http.routers.wrb-${{ env.BRANCH_NAME }}.tls.certresolver=lets-encrypt" \
            --label "traefik.http.services.wrb-${{ env.BRANCH_NAME }}.loadbalancer.server.port=80" \
            --label "traefik.http.routers.wrb-${{ env.BRANCH_NAME }}.middlewares=test-redirectscheme@file" \
            -v /home/ubuntu/features/${{ env.BRANCH_NAME }}:/var/www/html \
            --add-host=host.docker.internal:host-gateway \
            ${{ env.DOCKER_IMAGE }}
          EOF

      - name: Restart Docker container
        if: github.event_name == 'push' && env.CONTAINER_EXISTS == 'true'
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<'EOF'
          docker restart wrb-${{ env.BRANCH_NAME }}
          EOF

      - name: Fix Permissions
        if: github.event_name == 'push'
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          docker exec -u root wrb-${{ env.BRANCH_NAME }} chown -R www-data:www-data /var/www/html
          docker exec -u root wrb-${{ env.BRANCH_NAME }} chown -R www-data:www-data /var/www/html/storage
          docker exec -u root wrb-${{ env.BRANCH_NAME }} chown -R www-data:www-data /var/www/html/bootstrap/cache
          EOF

      - name: Remove vendor directory in Docker container
        if: github.event_name == 'delete' && (success() || failure())
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          docker exec wrb-${{ env.BRANCH_NAME }} rm -rf /var/www/html/vendor
          docker exec wrb-${{ env.BRANCH_NAME }} rm -rf /var/www/html/node_modules
          docker exec wrb-${{ env.BRANCH_NAME }} rm -rf /var/www/html/storage
          docker exec wrb-${{ env.BRANCH_NAME }} rm -rf /var/www/html/public
          docker exec wrb-${{ env.BRANCH_NAME }} rm -rf /var/www/html/bootstrap
          EOF

      - name: Stop Docker container
        if: github.event_name == 'delete' && (success() || failure())
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          docker stop wrb-${{ env.BRANCH_NAME }}
          docker rm wrb-${{ env.BRANCH_NAME }}
          EOF

      - name: Remove application data
        if: github.event_name == 'delete' && (success() || failure())
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          rm -rf /home/ubuntu/features/${{ env.BRANCH_NAME }}
          EOF

      - name: Remove database
        if: github.event_name == 'delete' && (success() || failure())
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          mysql -e 'DROP DATABASE feature_${{ env.DB_BRANCH_NAME }}'
          EOF


  migrate_and_build:
    needs: setup_and_deploy
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - name: Define environment variables
        env:
          BRANCH_NAME: ${{ needs.setup_and_deploy.outputs.BRANCH_NAME }}
        run: |
          echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV

      - name: Setup SSH for second job
        uses: webfactory/ssh-agent@v0.8.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Install Composer dependencies
        if: github.event_name == 'push'
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          docker exec wrb-${{ env.BRANCH_NAME }} bash -c "cd /var/www/html && composer install"
          EOF

      - name: Run Laravel migrations
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          docker exec wrb-${{ env.BRANCH_NAME }} php artisan migrate --force
          EOF

      - name: Build assets
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} <<EOF
          docker exec wrb-${{ env.BRANCH_NAME }} /bin/bash -l -c "cd /var/www/html && yarn && yarn run dev"
          EOF
