# Expected secrets
# GOOGLE_PLAY_CLOUD_PROJECT - Google Cloud project associated with Google Play
# GOOGLE_PLAY_SERVICE_ACCOUNT - Email address of service account
# GOOGLE_PLAY_SERVICE_ACCOUNT_KEY - Google Play Service Account key to authorize on Google Play
# GOOGLE_PLAY_PUBLISHER_API_KEY - Google Play Publisher API key to authorize the publisher on Google Play API
# GOOGLE_PLAY_WORKLOAD_IDENTITY_PROVIDER - Workload identity provider to generate temporary service account key
# UPLOAD_KEYSTORE_BASE_64 - The upload signing key for the app
# UPLOAD_KEYSTORE_PASSWORD - The password for UPLOAD_KEYSTORE_BASE_64
# UPLOAD_KEY_ALIAS - The key alias inside UPLOAD_KEYSTORE_BASE_64
# UPLOAD_KEY_ALIAS_PASSWORD - The password for the key alias
# FIREBASE_DEBUG_JSON_BASE64 - Optional JSON to enable Firebase (e.g. Crashlytics) for debug builds
# FIREBASE_RELEASE_JSON_BASE64 - Optional JSON to enable Firebase (e.g. Crashlytics) for release builds

name: Deploy

on:
  workflow_dispatch:
  push:
    branches:
      - main
    paths-ignore:
      - '.github/ISSUE_TEMPLATE/*'
      - '.github/PULL_REQUEST_TEMPLATE.md'
      - 'LICENSE'
      - 'README.md'
      - 'docs/**'

concurrency: deploy

jobs:
  validate_gradle_wrapper:
    permissions:
      contents: read
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        timeout-minutes: 1
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
      - name: Gradle Wrapper Validation
        timeout-minutes: 1
        uses: gradle/actions/wrapper-validation@v4

  check_secrets:
    environment: deployment
    permissions:
      contents: read
    runs-on: ubuntu-latest
    outputs:
      has-secrets: ${{ steps.check_secrets.outputs.defined }}
    steps:
      - id: check_secrets
        env:
          GOOGLE_PLAY_CLOUD_PROJECT: ${{ secrets.GOOGLE_PLAY_CLOUD_PROJECT }}
          # TODO [#1033]: Use token-based authorization on Google Play for automated deployment
          # TODO [#1033]: https://github.com/Electric-Coin-Company/zashi-android/issues/1033
          # Note that these properties are not currently used due to #1033
          # GOOGLE_PLAY_SERVICE_ACCOUNT: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT }}
          # GOOGLE_PLAY_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GOOGLE_PLAY_WORKLOAD_IDENTITY_PROVIDER }}
          GOOGLE_PLAY_SERVICE_ACCOUNT_KEY: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY }}
          GOOGLE_PLAY_PUBLISHER_API_KEY: ${{ secrets.GOOGLE_PLAY_PUBLISHER_API_KEY }}
          COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
        if: "${{ env.GOOGLE_PLAY_CLOUD_PROJECT != '' &&  
          env.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY != '' && 
          env.GOOGLE_PLAY_PUBLISHER_API_KEY != '' &&
          env.COINBASE_APP_ID != ''      
        }}"
        run: echo "defined=true" >> $GITHUB_OUTPUT

  build_and_deploy:
    if: needs.check_secrets.outputs.has-secrets == 'true'
    needs: [validate_gradle_wrapper, check_secrets]
    environment: deployment
    permissions:
      contents: read
      id-token: write
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        timeout-minutes: 1
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
        with:
          ref: main
          fetch-depth: 0  # To fetch all commits
      - name: Set up Java
        uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00
        timeout-minutes: 1
        with:
          distribution: 'temurin'
          java-version: 17
      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v4
        timeout-minutes: 10
        with:
          gradle-home-cache-cleanup: true
      - name: Export Google Services JSON
        env:
          FIREBASE_DEBUG_JSON_BASE64: ${{ secrets.FIREBASE_DEBUG_JSON_BASE64 }}
          FIREBASE_RELEASE_JSON_BASE64: ${{ secrets.FIREBASE_RELEASE_JSON_BASE64 }}
        if: "${{ env.FIREBASE_DEBUG_JSON_BASE64 != '' && env.FIREBASE_RELEASE_JSON_BASE64 != '' }}"
        shell: bash
        run: |
          mkdir -p app/src/debug/
          mkdir -p app/src/release/
          echo ${FIREBASE_DEBUG_JSON_BASE64} | base64 --decode > app/src/debug/google-services.json
          echo ${FIREBASE_RELEASE_JSON_BASE64} | base64 --decode > app/src/release/google-services.json
      - name: Authenticate to Google Cloud for Google Play
        # TODO [#1033]: Use token-based authorization on Google Play for automated deployment
        # TODO [#1033]: https://github.com/Electric-Coin-Company/zashi-android/issues/1033
        # Note that this step is not currently used due to #1033
        if: false
        id: auth_google_play
        uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f
        with:
          create_credentials_file: true
          project_id: ${{ secrets.GOOGLE_PLAY_CLOUD_PROJECT }}
          service_account: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT }}
          workload_identity_provider: ${{ secrets.GOOGLE_PLAY_WORKLOAD_IDENTITY_PROVIDER }}
          access_token_lifetime: '1500s'
      - name: Set Env
        shell: bash
        run: |
          echo "home=${HOME}" >> "$GITHUB_ENV"
      - name: Export Signing Key
        env:
          # The upload key must be exported using `base64 -w 0 <filename.jks>` for use
          # as a Github Secrets value; if the key is exported with standard wrapping,
          # it will fail to import correctly.
          # NOTE: This is the upload signing key, which may be replaced at will, not
          # the application signing key which is escrowed by Google and may only be
          # replaced once a year (and has a bunch of additional hassles associated with
          # replacing it.)
          SIGNING_KEYSTORE_BASE_64: ${{ secrets.UPLOAD_KEYSTORE_BASE_64 }}
          SIGNING_KEY_PATH: ${{ format('{0}/release.jks', env.home) }}
        shell: bash
        run: |
          echo ${SIGNING_KEYSTORE_BASE_64} | base64 --decode > ${SIGNING_KEY_PATH}
      - name: Upload to Play Store
        timeout-minutes: 25
        env:
          # TODO [#1033]: Use token-based authorization on Google Play for automated deployment
          # TODO [#1033]: https://github.com/Electric-Coin-Company/zashi-android/issues/1033
          # Note that these properties are not currently used due to #1033
          # ORG_GRADLE_PROJECT_ZCASH_GOOGLE_PLAY_SERVICE_ACCOUNT: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT }}
          # ORG_GRADLE_PROJECT_ZCASH_GOOGLE_PLAY_SERVICE_KEY_FILE_PATH: ${{ steps.auth_google_play.outputs.credentials_file_path }}
          ORG_GRADLE_PROJECT_ZCASH_GOOGLE_PLAY_SERVICE_ACCOUNT_KEY: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY }}
          ORG_GRADLE_PROJECT_ZCASH_GOOGLE_PLAY_PUBLISHER_API_KEY: ${{ secrets.GOOGLE_PLAY_PUBLISHER_API_KEY }}
          ORG_GRADLE_PROJECT_ZCASH_GOOGLE_PLAY_DEPLOY_TRACK: internal
          ORG_GRADLE_PROJECT_ZCASH_GOOGLE_PLAY_DEPLOY_STATUS: completed
          ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEYSTORE_PATH: ${{ format('{0}/release.jks', env.home) }}
          ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
          ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS: ${{ secrets.UPLOAD_KEY_ALIAS }}
          ORG_GRADLE_PROJECT_ZCASH_RELEASE_KEY_ALIAS_PASSWORD: ${{ secrets.UPLOAD_KEY_ALIAS_PASSWORD }}
          ORG_GRADLE_PROJECT_ZCASH_COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
          ORG_GRADLE_PROJECT_ZCASH_FLEXA_KEY: ${{ secrets.FLEXA_PUBLISHABLE_KEY }}
        run: |
          ./gradlew :app:publishToGooglePlay
      - name: Collect Artifacts
        timeout-minutes: 1
        env:
          ARTIFACTS_DIR_PATH: ${{ format('{0}/artifacts', env.home) }}
          BINARIES_ZIP_PATH: ${{ format('{0}/artifacts/binaries.zip', env.home) }}
          MAPPINGS_ZIP_PATH: ${{ format('{0}/artifacts/mappings.zip', env.home) }}
        run: |
          mkdir ${ARTIFACTS_DIR_PATH}
          zip -r ${BINARIES_ZIP_PATH} . -i app/build/outputs/apk/\*/\*.apk app/build/outputs/apk_from_bundle/\*/\*.apk app/build/outputs/bundle/\*/\*.aab
          zip -r ${MAPPINGS_ZIP_PATH} . -i app/build/outputs/mapping/\*/mapping.txt
      - name: Upload Artifacts
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
        timeout-minutes: 5
        with:
          name: Binaries
          path: ~/artifacts

# Due to how the Gradle publishing plugin works, this scan happens after the upload to Google Play.
# Rather than being preventative, this is primarily an "early warning system" to verify that our
# binaries aren't being misclassified as malware.
  antivirus:
    needs: [build_and_deploy]
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - name: Checkout
        timeout-minutes: 1
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
      - name: Download release artifact
        uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
        with:
          name: Binaries
      - name: Unzip artifacts
        timeout-minutes: 1
        run: |
          unzip binaries.zip
      - name: Antivirus
        timeout-minutes: 12
        with:
          path-to-scan: .
        uses: ./.github/actions/antivirus
