name: Scheduled assets update

# NOTE: This Github Actions is required by other actions, for preparing other packaging assets in a
#       routine manner, for example: GeoIP/GeoSite.
#       Currently updating:
#       - Geodat (GeoIP/Geosite)
#       - Wintun (wintun.dll)

on:
  workflow_dispatch:
  schedule:
    # Update GeoData on every day (22:30 UTC)
    - cron: "30 22 * * *"
  push:
    # Prevent triggering update request storm
    paths:
      - ".github/workflows/scheduled-assets-update.yml"
  pull_request:
    # Prevent triggering update request storm
    paths:
      - ".github/workflows/scheduled-assets-update.yml"

jobs:
  geodat:
    if: github.event.schedule == '30 22 * * *' || github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
    runs-on: ubuntu-latest
    steps:
      - name: Restore Geodat Cache
        uses: actions/cache/restore@v6
        with:
          path: resources
          key: xray-geodat-

      - name: Update Geodat
        id: update
        uses: nick-fields/retry@v4
        with:
          timeout_minutes: 60
          retry_wait_seconds: 60
          max_attempts: 60
          command: |
            [ -d 'resources' ] || mkdir resources
            LIST=('Loyalsoldier v2ray-rules-dat geoip geoip' 'Loyalsoldier v2ray-rules-dat geosite geosite')
            for i in "${LIST[@]}"
            do
              INFO=($(echo $i | awk 'BEGIN{FS=" ";OFS=" "} {print $1,$2,$3,$4}'))
              FILE_NAME="${INFO[3]}.dat"
              echo -e "Verifying HASH key..."
              HASH="$(curl -sL -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "https://raw.githubusercontent.com/${INFO[0]}/${INFO[1]}/release/${INFO[2]}.dat.sha256sum" | awk -F ' ' '{print $1}')"
              if [ -s "./resources/${FILE_NAME}" ] && [ "$(sha256sum "./resources/${FILE_NAME}" | awk -F ' ' '{print $1}')" == "${HASH}" ]; then
                  continue
              else
                  echo -e "Downloading https://raw.githubusercontent.com/${INFO[0]}/${INFO[1]}/release/${INFO[2]}.dat..."
                  curl -L -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "https://raw.githubusercontent.com/${INFO[0]}/${INFO[1]}/release/${INFO[2]}.dat" -o ./resources/${FILE_NAME}
                  echo -e "Verifying HASH key..."
                  [ "$(sha256sum "./resources/${FILE_NAME}" | awk -F ' ' '{print $1}')" == "${HASH}" ] || { echo -e "The HASH key of ${FILE_NAME} does not match cloud one."; exit 1; }
                  echo "unhit=true" >> $GITHUB_OUTPUT
              fi
            done

      - name: Save Geodat Cache
        uses: actions/cache/save@v6
        if: ${{ steps.update.outputs.unhit }}
        with:
          path: resources
          key: xray-geodat-${{ github.sha }}-${{ github.run_number }}

  wintun:
    if: github.event.schedule == '30 22 * * *' || github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
    runs-on: ubuntu-latest
    env:
      ASSETVER: 0.14.1
      ASSETHASH: 07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51
    steps:
      - name: Restore Wintun Cache
        uses: actions/cache/restore@v6
        with:
          path: resources
          key: xray-wintun-

      - name: Force downloading if run manually or on file update
        if: github.event_name == 'workflow_dispatch' || github.event_name == 'push'
        run: |
          echo "FORCE_UPDATE=true" >> $GITHUB_ENV

      - name: Update Wintun
        id: update
        uses: nick-fields/retry@v4
        with:
          timeout_minutes: 60
          retry_wait_seconds: 60
          max_attempts: 60
          command: |
            [ -d 'resources' ] || mkdir resources
            LIST=('amd64' 'x86' 'arm64')
            for ARCHITECTURE in "${LIST[@]}"
            do
              FILE_PATH="resources/wintun/bin/${ARCHITECTURE}/wintun.dll"
              echo -e "Checking if wintun.dll for ${ARCHITECTURE} exists..."
              if [ -s "./resources/wintun/bin/${ARCHITECTURE}/wintun.dll" ]; then
                  echo -e "wintun.dll for ${ARCHITECTURE} exists"
              else
                  echo -e "wintun.dll for ${ARCHITECTURE} is missing"
                  missing=true
              fi
            done
            if [ -s "./resources/wintun/LICENSE.txt" ]; then
              echo -e "LICENSE for Wintun exists"
            else
              echo -e "LICENSE for Wintun is missing"
              missing=true
            fi
            if [[ -v FORCE_UPDATE ]]; then
              missing=true
            fi
            if [[ "$missing" == true ]]; then
              FILENAME=wintun.zip
              DOWNLOAD_FILE=wintun-${ASSETVER}.zip
              echo -e "Downloading https://www.wintun.net/builds/${DOWNLOAD_FILE}..."
              curl -L "https://www.wintun.net/builds/${DOWNLOAD_FILE}" -o "${FILENAME}"
              if [[ "$(sha256sum "./${FILENAME}" | awk -F ' ' '{print $1}')" == "${ASSETHASH}" ]]; then
                echo -e "Unpacking wintun..."
                unzip -u ${FILENAME} -d resources/
                echo "unhit=true" >> $GITHUB_OUTPUT
              else
                echo -e "Digest of ${FILENAME} mismatch."
                exit 1
              fi
            fi

      - name: Save Wintun Cache
        uses: actions/cache/save@v6
        if: ${{ steps.update.outputs.unhit }}
        with:
          path: resources
          key: xray-wintun-${{ github.sha }}-${{ github.run_number }}
