name: Build, Test and Deploy

on:
  push:
    branches: [main, int, dev]

concurrency:
  group: print-calculator-${{ gitea.ref }}
  cancel-in-progress: true

jobs:
  test-backend:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'

      - name: Cache Gradle
        uses: actions/cache@v4
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: gradle-${{ runner.os }}-${{ hashFiles('backend/gradle/wrapper/gradle-wrapper.properties', 'backend/**/*.gradle*', 'backend/gradle.properties') }}
          restore-keys: |
            gradle-${{ runner.os }}-

      - name: Run Tests with Gradle
        run: |
          cd backend
          chmod +x gradlew
          ./gradlew test

  build-and-push:
    needs: test-backend
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set TAG + OWNER lowercase
        shell: bash
        run: |
          if [[ "${{ gitea.ref }}" == "refs/heads/main" ]]; then
            echo "TAG=prod" >> "$GITHUB_ENV"
          elif [[ "${{ gitea.ref }}" == "refs/heads/int" ]]; then
            echo "TAG=int" >> "$GITHUB_ENV"
          else
            echo "TAG=dev" >> "$GITHUB_ENV"
          fi

          echo "OWNER_LOWER=$(echo '${{ gitea.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"

      - name: Ensure docker CLI exists
        shell: bash
        run: |
          if ! command -v docker >/dev/null 2>&1; then
            apt-get update
            apt-get install -y --no-install-recommends docker.io
          fi
          docker version

      - name: Login to Gitea Registry
        shell: bash
        run: |
          set -euo pipefail
          printf '%s' "${{ secrets.REGISTRY_TOKEN }}" | docker login "${{ secrets.REGISTRY_URL }}" \
            -u "${{ secrets.REGISTRY_USER }}" --password-stdin

      - name: Build & Push Backend
        shell: bash
        run: |
          BACKEND_IMAGE="${{ secrets.REGISTRY_URL }}/${{ env.OWNER_LOWER }}/print-calculator-backend:${{ env.TAG }}"
          docker build -t "$BACKEND_IMAGE" ./backend
          docker push "$BACKEND_IMAGE"

      - name: Build & Push Frontend
        shell: bash
        run: |
          FRONTEND_IMAGE="${{ secrets.REGISTRY_URL }}/${{ env.OWNER_LOWER }}/print-calculator-frontend:${{ env.TAG }}"
          docker build -t "$FRONTEND_IMAGE" ./frontend
          docker push "$FRONTEND_IMAGE"

  deploy:
    needs: build-and-push
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set ENV
        shell: bash
        run: |
          if [[ "${{ gitea.ref }}" == "refs/heads/main" ]]; then
            echo "ENV=prod" >> "$GITHUB_ENV"
          elif [[ "${{ gitea.ref }}" == "refs/heads/int" ]]; then
            echo "ENV=int" >> "$GITHUB_ENV"
          else
            echo "ENV=dev" >> "$GITHUB_ENV"
          fi

      - name: Setup SSH key
        shell: bash
        run: |
          set -euo pipefail

          apt-get update
          apt-get install -y --no-install-recommends openssh-client

          mkdir -p ~/.ssh
          chmod 700 ~/.ssh

          # 1) Prende il secret base64 e rimuove spazi/newline/CR
          printf '%s' "${{ secrets.SSH_PRIVATE_KEY_B64 }}" | tr -d '\r\n\t ' > /tmp/key.b64

          # 2) (debug sicuro) stampa solo la lunghezza della base64
          echo "b64_len=$(wc -c < /tmp/key.b64)"

          # 3) Decodifica in chiave privata
          base64 -d /tmp/key.b64 > ~/.ssh/id_ed25519

          # 4) Rimuove eventuali CRLF dentro la chiave (se proviene da Windows)
          tr -d '\r' < ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.clean
          mv ~/.ssh/id_ed25519.clean ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519

          # 5) Validazione: se fallisce qui, la chiave NON è valida/corrotta
          ssh-keygen -y -f ~/.ssh/id_ed25519 >/dev/null

          ssh-keyscan -H "${{ secrets.SERVER_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null

      - name: Write env to server
        shell: bash
        run: |
          # 1. Start with the static env file content
          cat "deploy/envs/${{ env.ENV }}.env" > /tmp/full_env.env

          # 2. Determine DB credentials
          if [[ "${{ env.ENV }}" == "prod" ]]; then
            DB_URL="${{ secrets.DB_URL_PROD }}"
            DB_USER="${{ secrets.DB_USERNAME_PROD }}"
            DB_PASS="${{ secrets.DB_PASSWORD_PROD }}"
          elif [[ "${{ env.ENV }}" == "int" ]]; then
            DB_URL="${{ secrets.DB_URL_INT }}"
            DB_USER="${{ secrets.DB_USERNAME_INT }}"
            DB_PASS="${{ secrets.DB_PASSWORD_INT }}"
          else
            DB_URL="${{ secrets.DB_URL_DEV }}"
            DB_USER="${{ secrets.DB_USERNAME_DEV }}"
            DB_PASS="${{ secrets.DB_PASSWORD_DEV }}"
          fi

          # 3. Append DB credentials
          printf '\nDB_URL=%s\nDB_USERNAME=%s\nDB_PASSWORD=%s\n' \
            "$DB_URL" "$DB_USER" "$DB_PASS" >> /tmp/full_env.env

          # 4. Debug: print content (for debug purposes)
          echo "Preparing to send env file with variables:"
          grep -v "PASSWORD" /tmp/full_env.env || true

          # 5. Send to server
          ssh -i ~/.ssh/id_ed25519 -o BatchMode=yes "${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}" \
            "setenv ${{ env.ENV }}" < /tmp/full_env.env
            


      - name: Trigger deploy on Unraid (forced command key)
        shell: bash
        run: |
          set -euo pipefail

          # Aggiungiamo le opzioni di verbosità se dovesse fallire ancora, 
          # e assicuriamoci che l'input sia pulito
          ssh -i ~/.ssh/id_ed25519 -o BatchMode=yes "${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}" "deploy ${{ env.ENV }}"
