name: Fleetbase CI/CD

on:
  push:
    branches: ["deploy/*"]

concurrency:
  group: ${{ github.ref }}
  cancel-in-progress: true

env:
  PROJECT: ${{ secrets.PROJECT }}
  GITHUB_AUTH_KEY: ${{ secrets._GITHUB_AUTH_TOKEN }}

jobs:
  build_service:
    name: Build and Deploy the Service
    runs-on: ubuntu-latest
    permissions:
      id-token: write # This is required for requesting the JWT
      contents: read # This is required for actions/checkout

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3
        with:
          submodules: recursive

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

      - name: Set Dynamic ENV Vars
        run: |
          SHORT_COMMIT=$(echo $GITHUB_SHA | cut -c -8)
          echo "VERSION=${SHORT_COMMIT}" >> $GITHUB_ENV
          echo "STACK=$(basename $GITHUB_REF)" >> $GITHUB_ENV

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_NUMBER }}:role/${{ env.PROJECT }}-${{ env.STACK }}-deployer
          role-session-name: github
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build and Release
        uses: docker/bake-action@v2
        env:
          REGISTRY: ${{ steps.login-ecr.outputs.registry }}/${{ env.PROJECT }}-${{ env.STACK }}
          VERSION: ${{ env.VERSION }}
          GITHUB_AUTH_KEY: ${{ env.GITHUB_AUTH_KEY }}
          CACHE: type=gha
        with:
          push: true
          files: |
            ./docker-bake.hcl

      - name: Resolve ECS Targets
        run: |
          set -euo pipefail

          # Detect naming scheme by checking if new cluster exists
          NEW_CLUSTER="${PROJECT}-${STACK}-cluster"
          if aws ecs describe-clusters --region "${AWS_REGION}" --clusters "${NEW_CLUSTER}" \
              --query "clusters[?status=='ACTIVE'].clusterArn" --output text 2>/dev/null | grep -q .; then
            # New scheme: use cluster suffix and service prefixes
            CLUSTER="${NEW_CLUSTER}"
            SERVICE_PREFIX="${PROJECT}-${STACK}-"
            SERVICE_BASE="api"
          else
            # Legacy scheme: no suffixes/prefixes
            CLUSTER="${PROJECT}-${STACK}"
            SERVICE_PREFIX=""
            SERVICE_BASE="app"
          fi

          # Build service names
          API_SERVICE="${SERVICE_PREFIX}${SERVICE_BASE}"
          SCHEDULER_SERVICE="${SERVICE_PREFIX}scheduler"
          EVENTS_SERVICE="${SERVICE_PREFIX}events"
          TASK_DEF="${PROJECT}-${STACK}-${SERVICE_BASE}"
          
          # Get container name from task definition
          CONTAINER_NAME="$(aws ecs describe-task-definition --task-definition "$TASK_DEF" \
              --query 'taskDefinition.containerDefinitions[0].name' --output text 2>/dev/null || echo "$SERVICE_BASE")"

          {
            echo "CLUSTER=$CLUSTER"
            echo "API_SERVICE=$API_SERVICE"
            echo "SCHEDULER_SERVICE=$SCHEDULER_SERVICE"
            echo "EVENTS_SERVICE=$EVENTS_SERVICE"
            echo "TASK_DEF=$TASK_DEF"
            echo "CONTAINER_NAME=$CONTAINER_NAME"
          } >> "$GITHUB_ENV"
      - name: Download ecs-tool
        run: |
          wget -O ecs-tool.tar.gz https://github.com/springload/ecs-tool/releases/download/1.9.6/ecs-tool_1.9.6_linux_amd64.tar.gz && tar -xvf ecs-tool.tar.gz ecs-tool

      - name: Deploy the images 🚀
        run: |-
          set -eu
          
          # Run deploy.sh script before deployments
          env "ECS_RUN.SERVICE=${API_SERVICE}" "ECS_RUN.LAUNCH_TYPE=FARGATE" \
            ./ecs-tool run -l "ecs-tool" \
              --image_tag '{container_name}-${{ env.VERSION }}' \
              --cluster "${CLUSTER}" \
              --task_definition "${TASK_DEF}" \
              --container_name "${CONTAINER_NAME}" \
              ./deploy.sh

          # Deploy services
          ./ecs-tool deploy \
              --image_tag '{container_name}-${{ env.VERSION }}' \
              --cluster "${CLUSTER}" \
              -s "${API_SERVICE}" -s "${SCHEDULER_SERVICE}" -s "${EVENTS_SERVICE}"

  build_frontend:
    name: Build and Deploy the Console
    needs: [build_service]
    runs-on: ubuntu-latest
    permissions:
      id-token: write # This is required for requesting the JWT
      contents: read # This is required for actions/checkout

    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          submodules: true

      - name: Set Dynamic ENV Vars
        run: |
          SHORT_COMMIT=$(echo $GITHUB_SHA | cut -c -8)
          echo "VERSION=${SHORT_COMMIT}" >> $GITHUB_ENV
          echo "STACK=$(basename $GITHUB_REF)" >> $GITHUB_ENV

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_NUMBER }}:role/${{ env.PROJECT }}-${{ env.STACK }}-deployer
          role-session-name: github
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Get infra-provided configuration
        run: |
          set -eu

          wget -O- https://github.com/springload/ssm-parent/releases/download/1.8.0/ssm-parent_1.8.0_linux_amd64.tar.gz | tar xvzf - ssm-parent

          ./ssm-parent -n /actions/${{ env.PROJECT }}/${{ env.STACK }}/configuration dotenv /tmp/dotenv.file
          # remove double quotes and pipe into the env
          cat /tmp/dotenv.file | sed -e 's/"//g' >> $GITHUB_ENV

      - name: Install Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - uses: pnpm/action-setup@v4
        name: Install pnpm
        id: pnpm-install
        with:
          version: 9.5.0
          run_install: false

      - name: Get pnpm Store Directory
        id: pnpm-cache
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

      - uses: actions/cache@v3
        name: Setup pnpm Cache
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-

      - name: Create and Setup .npmrc
        run: |
          if [[ -n "${{ secrets._GITHUB_AUTH_TOKEN }}" ]]; then
            echo "//npm.pkg.github.com/:_authToken=${{ secrets._GITHUB_AUTH_TOKEN }}" > .npmrc
          fi
          if [[ -n "${{ secrets.FLEETBASE_REGISTRY_TOKEN }}" ]]; then
            echo "//registry.fleetbase.io/:_authToken=${{ secrets.FLEETBASE_REGISTRY_TOKEN }}" >> .npmrc
            echo "@fleetbase:registry=https://registry.fleetbase.io" >> .npmrc
          fi
        working-directory: ./console

      - name: Set Env Variables for QA
        if: startsWith(github.ref, 'refs/heads/deploy/qa')
        run: |
          echo "STRIPE_KEY=${{ secrets.STRIPE_TEST_KEY }}" >> ./environments/.env.production
          echo "LOGROCKET_APP_ID=${{ secrets.LOGROCKET_APP_ID }}" >> ./environments/.env.production
          echo "EXTENSIONS=@fleetbase/billing-engine,@fleetbase/internals-engine" >> ./environments/.env.production
        working-directory: ./console

      - name: Set Env Variables for Production
        if: startsWith(github.ref, 'refs/heads/deploy/production')
        run: |
          echo "STRIPE_KEY=${{ secrets.STRIPE_KEY }}" >> ./environments/.env.production
          echo "LOGROCKET_APP_ID=${{ secrets.LOGROCKET_APP_ID }}" >> ./environments/.env.production
          echo "EXTENSIONS=@fleetbase/billing-engine,@fleetbase/internals-engine" >> ./environments/.env.production
        working-directory: ./console

      - name: Install dependencies
        run: pnpm install
        working-directory: ./console

      - name: Build
        run: |
          set -eu

          pnpm build --environment production
        working-directory: ./console

      - name: Deploy Console 🚀
        run: |
          set -u

          DEPLOY_BUCKET=${STATIC_DEPLOY_BUCKET:-${{ env.PROJECT }}-${{ env.STACK }}}
          NEW_BUCKET="${PROJECT}-${STACK}-console"
          if aws s3api head-bucket --bucket "$NEW_BUCKET" 2>/dev/null; then
            DEPLOY_BUCKET="$NEW_BUCKET"
          fi

          # this value will come from the dotenv above
          echo "Deploying to $DEPLOY_BUCKET"
          wget -O- https://github.com/bep/s3deploy/releases/download/v2.11.0/s3deploy_2.11.0_linux-amd64.tar.gz | tar xzv -f - s3deploy
          ./s3deploy -region ${AWS_REGION} -source console/dist -bucket ${DEPLOY_BUCKET}
