# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Setup Custard
description: Sets up the Custard testing environment.

inputs:
  path:
    description: Path of the package to run.
    required: true
  ci-setup:
    description: The CI setup for the package path.
    required: true
  id-token:
    description: The ID token to export variable, not exported if not provided.
    required: false

runs:
  # TODO: This should all be handled by the local runner.
  #       When that's ready, we can call it directly and get rid of this.
  using: composite
  steps:
    - name: Export environment variables
      uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
      id: vars
      with:
        script: |
          function uniqueId(length = 6) {
            const min = 2 ** 32;
            const max = 2 ** 64;
            return Math.floor(Math.random() * max + min)
              .toString(36)
              .slice(0, length);
          }
          function substituteVars(value, env) {
            for (const key in env) {
              const re = new RegExp(`\\$(${key}\\b|\\{\\s*${key}\\s*\\})`, 'g');
              value = value.replaceAll(re, env[key]);
            }
            return value;
          }

          const setup = ${{ inputs.ci-setup }};

          // Define automatic variables plus custom variables.
          const vars = {
            PROJECT_ID: '${{ inputs.project-id }}',
            RUN_ID: uniqueId(),
            SERVICE_ACCOUNT: '${{ inputs.service-account }}',
            ...(setup.env || {}),
          };

          // Apply variable interpolation.
          const env = Object.fromEntries(
            Object.keys(vars).map(key => [key, substituteVars(vars[key], vars)])
          );

          // Export environment variables.
          console.log('env:');
          for (const key in env) {
            const value = env[key];
            console.log(`  ${key}: ${value}`);
            core.exportVariable(key, value);
          }

          // Show exported secrets, for logging purposes.
          // TODO: We might want to fetch the secrets here and export them directly.
          //       https://cloud.google.com/secret-manager/docs/create-secret-quickstart#secretmanager-quickstart-nodejs
          console.log('secrets:');
          for (const key in setup.secrets || {}) {
            // This is the Google Cloud Secret Manager secret ID.
            // NOT the secret value, so it's ok to show.
            console.log(`  ${key}: ${setup.secrets[key]}`);
          }

          // Set global secret for the Service Account identity token
          // Use in place of 'gcloud auth print-identity-token' or auth.getIdTokenClient
          // usage: curl -H 'Bearer: $ID_TOKEN' https://
          const idToken = '${{ inputs.id-token }}';
          if (idToken) {
            core.exportVariable('ID_TOKEN', idToken)
            core.setSecret(idToken)
            // For logging, show the source of the ID_TOKEN
            console.log(`  ID_TOKEN: steps.auth.outputs.id_token (from GitHub Action)`);
          }

          // Return env and secrets to use for further steps.
          return {
            env: env,
            // Transform secrets into the format needed for the GHA secret manager step.
            secrets: Object.keys(setup.secrets || {})
              .map(key => `${key}:${setup.secrets[key]}`)
              .join('\n'),
          };
    - name: Fetch secrets
      uses: google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce # v2
      if: ${{ fromJson(steps.vars.outputs.result).secrets }}
      with:
        secrets: ${{ fromJson(steps.vars.outputs.result).secrets }}
        export_to_environment: true
