name: 🛠️ Build Website

on:
  workflow_call:
    inputs:
      config:
        type: string
        default: build
      ref:
        required: true
        type: string
      repo:
        required: true
        type: string
      lang:
        type: string
        default: en
      context:
        type: string
        default: deploy-preview
      continue-on-error:
        type: boolean
        default: true
      privileged:
        type: boolean
        default: true
      strict:
        type: boolean
        default: false
      cache:
        type: boolean
        default: true

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    continue-on-error: ${{ inputs.continue-on-error }}
    permissions:
      contents: read

    steps:
      - name: Add GitHub Token to Environment
        run: |
          echo "GH_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> "$GITHUB_ENV"

      - name: Set Metadata
        if: inputs.config == 'build'
        run: |
          {
            echo "BUILD_CONTEXT=${{ inputs.context }}"
            echo "EXTRA_FLAGS=""$EXTRA_FLAGS" --production""
          } >> "$GITHUB_ENV"

      - name: Set Metadata for Privileged Builds
        if: inputs.privileged
        run: |
          echo "BUILD_INSIDERS=true" >> "$GITHUB_ENV"
          echo "EXTRA_FLAGS=""$EXTRA_FLAGS" --insiders"" >> "$GITHUB_ENV"

      - name: Set Metadata for International Builds
        if: inputs.lang != 'en'
        run: |
          echo "GITREVISIONDATE=false" >> "$GITHUB_ENV"
          echo "GITAUTHORS=false" >> "$GITHUB_ENV"

      - name: Set Metadata for Offline Mode
        if: inputs.config == 'offline'
        run: |
          {
            echo "EXTRA_FLAGS=""$EXTRA_FLAGS" --offline""
          } >> "$GITHUB_ENV"

      - name: Set Metadata for Strict Mode
        if: inputs.strict
        run: |
          echo "EXTRA_FLAGS=""$EXTRA_FLAGS" --cmd_flags=--strict"" >> "$GITHUB_ENV"

      - name: Download Repository
        uses: actions/checkout@v4
        with:
          repository: ${{ inputs.repo }}
          ref: ${{ inputs.ref }}
          persist-credentials: "false"
          fetch-depth: 0

      - name: Download Submodules
        uses: actions/download-artifact@v4
        with:
          pattern: repo-*
          path: modules

      - name: Move mkdocs-material-insiders to mkdocs-material
        if: inputs.privileged
        run: |
          rmdir modules/mkdocs-material
          mv modules/repo-mkdocs-material-insiders modules/mkdocs-material

      - name: Move brand submodule to theme/assets/brand
        run: |
          rmdir theme/assets/brand
          mv modules/repo-brand theme/assets/brand

      - name: Copy Translation Files
        if: inputs.lang != 'en'
        run: |
          cp -rl modules/repo-i18n/i18n .
          cp -rl modules/repo-i18n/includes .

      - name: Install Python (pipenv)
        if: inputs.privileged
        uses: actions/setup-python@v5
        with:
          cache: "pipenv"

      - name: Install Python (no pipenv)
        if: ${{ !inputs.privileged }}
        uses: actions/setup-python@v5

      - name: Restore Privacy Plugin Cache
        uses: actions/cache/restore@v4
        id: privacy_cache_restore
        if: inputs.cache
        with:
          key: privacy-cache-${{ inputs.repo }}-${{ hashfiles('.cache/plugin/privacy/**') }}
          path: |
            .cache/plugin/privacy
          restore-keys: |
            privacy-cache-${{ inputs.repo }}-
            privacy-cache-privacyguides/privacyguides.org-
            privacy-cache-

      - name: Restore Social Plugin Cache
        uses: actions/cache/restore@v4
        id: social_cache_restore
        if: inputs.cache
        with:
          key: social-cache-${{ inputs.repo }}-${{ inputs.lang }}-${{ hashfiles('.cache/plugin/social/manifest.json') }}
          path: |
            .cache/plugin/social/manifest.json
            .cache/plugin/social/assets
          restore-keys: |
            social-cache-${{ inputs.repo }}-${{ inputs.lang }}-
            social-cache-privacyguides/privacyguides.org-${{ inputs.lang }}-

      - name: Restore Optimize Plugin Cache
        uses: actions/cache/restore@v4
        id: optimize_cache_restore
        if: inputs.cache
        with:
          key: optimize-cache-${{ inputs.repo }}-${{ hashfiles('.cache/plugin/optimize/manifest.json') }}
          path: |
            .cache/plugin/optimize
          restore-keys: |
            optimize-cache-${{ inputs.repo }}-
            optimize-cache-privacyguides/privacyguides.org-
            optimize-cache-

      - name: Install Python Dependencies
        if: inputs.privileged
        run: |
          pip install pipenv
          pipenv install
          sudo apt install pngquant

      - name: Install Python Dependencies (Unprivileged)
        if: ${{ !inputs.privileged }}
        run: |
          pip install mkdocs-material
          sudo apt install pngquant
          echo "EXTRA_FLAGS=""$EXTRA_FLAGS" --cmd=mkdocs"" >> "$GITHUB_ENV"

      - name: Build Website
        run: |
          eval ./run.sh --build --lang=${{ inputs.lang }} "$EXTRA_FLAGS"

      - name: Run index-generation.sh for top posts
        if: inputs.lang == 'en'
        run: |
          bash index-generation.sh \
            --source='https://discuss.privacyguides.net/top.json?period=weekly' \
            --tag="top posts" \
            --destination="./site/en/index.html" \
            --count=3

      - name: Run index-generation.sh for latest posts
        if: inputs.lang == 'en'
        run: |
          bash index-generation.sh \
            --source='https://discuss.privacyguides.net/latest.json' \
            --tag="latest posts" \
            --destination="./site/en/index.html" \
            --count=12

      - name: Package Website
        run: |
          tar -czf site-${{ inputs.config }}-${{ inputs.lang }}.tar.gz site

      - name: Find Privacy Plugin Cache
        uses: actions/cache/restore@v4
        if: steps.privacy_cache_restore.outputs.cache-hit != 'true' && inputs.cache
        id: privacy_cache_test
        with:
          key: privacy-cache-privacyguides/privacyguides.org-${{ hashfiles('.cache/plugin/privacy/**') }}
          lookup-only: true
          path: |
            .cache/plugin/privacy

      - name: Find Social Plugin Cache
        uses: actions/cache/restore@v4
        if: steps.social_cache_restore.outputs.cache-hit != 'true' && inputs.cache
        id: social_cache_test
        with:
          key: social-cache-privacyguides/privacyguides.org-${{ inputs.lang }}-${{ hashfiles('.cache/plugin/social/manifest.json') }}
          lookup-only: true
          path: |
            .cache/plugin/social/manifest.json
            .cache/plugin/social/assets

      - name: Find Optimize Plugin Cache
        uses: actions/cache/restore@v4
        if: steps.optimize_cache_restore.outputs.cache-hit != 'true' && inputs.cache
        id: optimize_cache_test
        with:
          key: optimize-cache-privacyguides/privacyguides.org-${{ hashfiles('.cache/plugin/optimize/manifest.json') }}
          lookup-only: true
          path: |
            .cache/plugin/optimize

      - name: Save Privacy Plugin Cache
        uses: actions/cache/save@v4
        if: steps.privacy_cache_test.outputs.cache-hit != 'true' && inputs.cache
        with:
          key: privacy-cache-${{ inputs.repo }}-${{ hashfiles('.cache/plugin/privacy/**') }}
          path: .cache/plugin/privacy

      - name: Save Social Plugin Cache
        uses: actions/cache/save@v4
        if: steps.social_cache_test.outputs.cache-hit != 'true' && inputs.cache
        with:
          key: social-cache-${{ inputs.repo }}-${{ inputs.lang }}-${{ hashfiles('.cache/plugin/social/manifest.json') }}
          path: |
            .cache/plugin/social/manifest.json
            .cache/plugin/social/assets

      - name: Save Optimize Plugin Cache
        uses: actions/cache/save@v4
        if: steps.optimize_cache_test.outputs.cache-hit != 'true' && inputs.cache
        with:
          key: optimize-cache-${{ inputs.repo }}-${{ hashfiles('.cache/plugin/optimize/manifest.json') }}
          path: .cache/plugin/optimize

      - name: Upload Site
        uses: actions/upload-artifact@v4
        with:
          name: site-${{ inputs.config }}-${{ inputs.lang }}.tar.gz
          path: site-${{ inputs.config }}-${{ inputs.lang }}.tar.gz
          retention-days: 1

  offline_package:
    if: inputs.config == 'offline' && inputs.lang == 'en'
    needs: build
    runs-on: ubuntu-latest
    continue-on-error: ${{ inputs.continue-on-error }}
    permissions:
      contents: read

    steps:
      - uses: actions/download-artifact@v4
        with:
          name: site-offline-en.tar.gz

      - run: |
          tar -xzf site-offline-en.tar.gz
          tar -czf offline.tar.gz site/en
          zip -r -q offline.zip site/en

      - name: Upload tar.gz file
        uses: actions/upload-artifact@v4
        with:
          name: offline.tar.gz
          path: offline.tar.gz

      - name: Upload zip file
        uses: actions/upload-artifact@v4
        with:
          name: offline.zip
          path: offline.zip

      - name: Create ZIM File
        uses: addnab/docker-run-action@v3
        with:
          image: ghcr.io/openzim/zim-tools:3.1.3
          options: -v ${{ github.workspace }}:/data
          run: |
            zimwriterfs -w index.html -I assets/brand/logos/png/square/pg-yellow.png -l eng -t "Privacy Guides" -d "Your central privacy and security resource to protect yourself online." -c "Privacy Guides" -p "Jonah Aragon" -n "Privacy Guides" -e "https://github.com/privacyguides/privacyguides.org" /data/site/en /data/offline-privacy_guides.zim

      - name: Upload ZIM file
        uses: actions/upload-artifact@v4
        with:
          name: offline-privacy_guides.zim
          path: offline-privacy_guides.zim