name: Build & Deploy

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  build-and-deploy:
    runs-on: freebsd
    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: npm ci

      - name: Build or restore sharp for FreeBSD
        run: |
          SHARP_VER=$(node -e "process.stdout.write(require('./node_modules/sharp/package.json').version)")
          CACHE_FILE=/usr/local/git/.cache/sharp-freebsd/sharp-freebsd-x64-${SHARP_VER}.node
          if [ -f "$CACHE_FILE" ]; then
            echo "Restoring cached sharp ${SHARP_VER}"
            mkdir -p node_modules/sharp/src/build/Release
            cp "$CACHE_FILE" node_modules/sharp/src/build/Release/sharp-freebsd-x64.node
          else
            echo "Building sharp ${SHARP_VER} from source..."
            npm install node-addon-api node-gyp
            npm install sharp --build-from-source
            mkdir -p /usr/local/git/.cache/sharp-freebsd
            BUILT=$(find node_modules/sharp -name "sharp-freebsd-x64.node" | head -1)
            if [ -n "$BUILT" ]; then
              cp "$BUILT" "$CACHE_FILE"
              echo "Cached sharp binary at $CACHE_FILE"
            fi
          fi

      - name: Fetch homepage config from node jail
        run: |
          mkdir -p ~/.ssh
          printf '%s\n' "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          mkdir -p content/.indiekit
          ssh -p 222 -o StrictHostKeyChecking=no \
            ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} \
            "sudo bastille cmd node cat /usr/local/indiekit/content/.indiekit/homepage.json" \
            > content/.indiekit/homepage.json

      - name: Build CSS
        run: npm run build:css

      - name: Create .env file
        env:
          SITE_URL: ${{ secrets.SITE_URL }}
          SITE_NAME: ${{ secrets.SITE_NAME }}
          SITE_SOCIAL: ${{ secrets.SITE_SOCIAL }}
          AUTHOR_NAME: ${{ secrets.AUTHOR_NAME }}
          SITE_DESCRIPTION: ${{ secrets.SITE_DESCRIPTION }}
          AUTHOR_BIO: ${{ secrets.AUTHOR_BIO }}
          AUTHOR_EMAIL: ${{ secrets.AUTHOR_EMAIL }}
          AUTHOR_LOCATION: ${{ secrets.AUTHOR_LOCATION }}
          GITHUB_USERNAME: ${{ secrets.GH_USERNAME }}
          MASTODON_INSTANCE: ${{ secrets.MASTODON_INSTANCE }}
          MASTODON_USER: ${{ secrets.MASTODON_USER }}
          BLUESKY_HANDLE: ${{ secrets.BLUESKY_HANDLE }}
          ACTIVITYPUB_HANDLE: ${{ secrets.ACTIVITYPUB_HANDLE }}
          AUTHOR_AVATAR: ${{ secrets.AUTHOR_AVATAR }}
          AUTHOR_TITLE: ${{ secrets.AUTHOR_TITLE }}
          AUTHOR_PRONOUN: ${{ secrets.AUTHOR_PRONOUN }}
          SITE_LOCALE: ${{ secrets.SITE_LOCALE }}
          OWNYOURSWARM_FEED_URL: ${{ secrets.OWNYOURSWARM_FEED_URL }}
          OWNYOURSWARM_FEED_TOKEN: ${{ secrets.OWNYOURSWARM_FEED_TOKEN }}
          LISTENING_FETCH_CACHE_DURATION: ${{ secrets.LISTENING_FETCH_CACHE_DURATION }}
          FUNKWHALE_FETCH_CACHE_DURATION: ${{ secrets.FUNKWHALE_FETCH_CACHE_DURATION }}
          LASTFM_FETCH_CACHE_DURATION: ${{ secrets.LASTFM_FETCH_CACHE_DURATION }}
        run: |
          {
            printf 'SITE_URL=%s\n' "$SITE_URL"
            printf 'SITE_NAME=%s\n' "$SITE_NAME"
            printf 'SITE_SOCIAL=%s\n' "$SITE_SOCIAL"
            printf 'AUTHOR_NAME=%s\n' "$AUTHOR_NAME"
            printf 'SITE_DESCRIPTION=%s\n' "$SITE_DESCRIPTION"
            printf 'AUTHOR_BIO=%s\n' "$AUTHOR_BIO"
            printf 'AUTHOR_EMAIL=%s\n' "$AUTHOR_EMAIL"
            printf 'AUTHOR_LOCATION=%s\n' "$AUTHOR_LOCATION"
            printf 'GITHUB_USERNAME=%s\n' "$GITHUB_USERNAME"
            printf 'MASTODON_INSTANCE=%s\n' "$MASTODON_INSTANCE"
            printf 'MASTODON_USER=%s\n' "$MASTODON_USER"
            printf 'BLUESKY_HANDLE=%s\n' "$BLUESKY_HANDLE"
            printf 'ACTIVITYPUB_HANDLE=%s\n' "$ACTIVITYPUB_HANDLE"
            printf 'AUTHOR_AVATAR=%s\n' "$AUTHOR_AVATAR"
            printf 'AUTHOR_TITLE=%s\n' "$AUTHOR_TITLE"
            printf 'AUTHOR_PRONOUN=%s\n' "$AUTHOR_PRONOUN"
            printf 'SITE_LOCALE=%s\n' "$SITE_LOCALE"
            printf 'OWNYOURSWARM_FEED_URL=%s\n' "$OWNYOURSWARM_FEED_URL"
            printf 'OWNYOURSWARM_FEED_TOKEN=%s\n' "$OWNYOURSWARM_FEED_TOKEN"
            printf 'LISTENING_FETCH_CACHE_DURATION=%s\n' "$LISTENING_FETCH_CACHE_DURATION"
            printf 'FUNKWHALE_FETCH_CACHE_DURATION=%s\n' "$FUNKWHALE_FETCH_CACHE_DURATION"
            printf 'LASTFM_FETCH_CACHE_DURATION=%s\n' "$LASTFM_FETCH_CACHE_DURATION"
          } > .env

      - name: Build site
        run: npm run build
        env:
          SITE_URL: ${{ secrets.SITE_URL }}
          SITE_NAME: ${{ secrets.SITE_NAME }}
          SITE_SOCIAL: ${{ secrets.SITE_SOCIAL }}
          SITE_DESCRIPTION: ${{ secrets.SITE_DESCRIPTION }}
          AUTHOR_NAME: ${{ secrets.AUTHOR_NAME }}
          ACTIVITYPUB_HANDLE: ${{ secrets.ACTIVITYPUB_HANDLE }}
          AUTHOR_AVATAR: ${{ secrets.AUTHOR_AVATAR }}
          AUTHOR_BIO: ${{ secrets.AUTHOR_BIO }}
          AUTHOR_EMAIL: ${{ secrets.AUTHOR_EMAIL }}
          GITHUB_USERNAME: ${{ secrets.GH_USERNAME }}
          MASTODON_INSTANCE: ${{ secrets.MASTODON_INSTANCE }}
          MASTODON_USER: ${{ secrets.MASTODON_USER }}
          BLUESKY_HANDLE: ${{ secrets.BLUESKY_HANDLE }}
          GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
          OWNYOURSWARM_FEED_URL: ${{ secrets.OWNYOURSWARM_FEED_URL }}
          OWNYOURSWARM_FEED_TOKEN: ${{ secrets.OWNYOURSWARM_FEED_TOKEN }}
          LISTENING_FETCH_CACHE_DURATION: ${{ secrets.LISTENING_FETCH_CACHE_DURATION }}
          FUNKWHALE_FETCH_CACHE_DURATION: ${{ secrets.FUNKWHALE_FETCH_CACHE_DURATION }}
          LASTFM_FETCH_CACHE_DURATION: ${{ secrets.LASTFM_FETCH_CACHE_DURATION }}
          INDIEKIT_URL: http://10.100.0.20:3000
          FUNKWHALE_INSTANCE: http://10.100.0.40:5000
          GITEA_URL: https://gitea.giersig.eu
          GITEA_ORG: giersig.eu

      - name: Deploy via rsync
        run: |
          mkdir -p ~/.ssh
          printf '%s\n' "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -p 222 ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
          cp .env _site/.env
          rsync -rlz --delete \
            --exclude='content/.indiekit/' \
            -e "ssh -p 222" \
            _site/ \
            ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/usr/local/bastille/jails/web/root/usr/local/www/blog/

      - name: Trigger syndication webhook
        env:
          SECRET: ${{ secrets.SECRET }}
          SITE_URL: ${{ secrets.SITE_URL }}
          INDIEKIT_INTERNAL_URL: http://10.100.0.20:3000
        run: |
          npm install --no-save jsonwebtoken
          TOKEN=$(node --input-type=commonjs <<'EOF'
          const jwt = require('jsonwebtoken');
          const token = jwt.sign(
            { me: process.env.SITE_URL, scope: 'update' },
            process.env.SECRET,
            { expiresIn: '10m' }
          );
          process.stdout.write(token);
          EOF
          )
          RESPONSE=$(curl -sS -w "\n%{http_code}" -X POST \
            -H "Content-Type: application/json" \
            -d "{\"access_token\": \"$TOKEN\"}" \
            "$INDIEKIT_INTERNAL_URL/syndicate")
          HTTP_CODE=$(echo "$RESPONSE" | tail -1)
          BODY=$(echo "$RESPONSE" | sed '$d')
          echo "HTTP $HTTP_CODE: $BODY"
          [ "$HTTP_CODE" -lt 400 ]
