# Copyright 2023 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
#
#     https://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: "tf-pull-request"
on:
  pull_request:
    branches:
      - "shared"

env:
  PROJECT_ID: ${{ secrets.PROJECT_ID }}
  TF_BACKEND: ${{ secrets.TF_BACKEND }}
  TF_VAR_gh_token: ${{ secrets.TF_VAR_gh_token }}
  TF_IN_AUTOMATION: "true"
  TF_VAR_github_app_infra_token: ${{ secrets.TF_VAR_github_app_infra_token }}

jobs:
  run:
    runs-on: "ubuntu-latest"
    permissions:
      contents: "read"
      id-token: "write"
      issues: "write"
      pull-requests: "write"

    steps:
      - uses: "actions/checkout@v3"

      - id: "auth"
        uses: "google-github-actions/auth@v1"
        with:
          token_format: "access_token"
          workload_identity_provider: ${{ secrets.WIF_PROVIDER_NAME }}
          service_account: ${{ secrets.SERVICE_ACCOUNT_EMAIL }}

      - uses: "google-github-actions/setup-gcloud@v1"
        with:
          install_components: "beta,terraform-tools"

      - uses: "hashicorp/setup-terraform@v2"
        with:
          terraform_version: "1.5.7"

      - id: setup
        shell: bash
        run: |
          echo "Adding bucket information to backends"
          for i in `find . -name 'backend.tf'`
          do
            sed -i'' -e "s/UPDATE_ME/${TF_BACKEND}/" $i
            sed -i'' -e "s/UPDATE_PROJECTS_BACKEND/${TF_BACKEND}/" $i
          done
          for i in `find . -name 'remote_bucket.tf'`
          do
            sed -i'' -e "s/UPDATE_ME/${TF_BACKEND}/" $i
          done
      - id: init
        run: |
          ${GITHUB_WORKSPACE}/tf-wrapper.sh init shared
      
      - id: plan
        run: |
          ${GITHUB_WORKSPACE}/tf-wrapper.sh plan shared
      
      - id: validate
        run: |
          ${GITHUB_WORKSPACE}/tf-wrapper.sh validate shared "${GITHUB_WORKSPACE}/policy-library" "${PROJECT_ID}" "FILESYSTEM" "GITHUB"

      - uses: actions/github-script@v6
        if: github.event_name == 'pull_request'
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const { data: comments } = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
            })
            const botComment = comments.find(comment => {
              return comment.user.type === 'Bot' && comment.body.includes('Terraform Initialization')
            })

            const run_url = process.env.GITHUB_SERVER_URL + '/' + process.env.GITHUB_REPOSITORY + '/actions/runs/' + process.env.GITHUB_RUN_ID
            const run_link = '<a href="' + run_url + '">Actions</a>.'
            const fs = require('fs')
            const plan_dir = 'tmp_plan'
            const plan_dir_files = fs.readdirSync('tmp_plan')
            const plan_files = plan_dir_files.filter(file => file.match(new RegExp(`.*\.(.txt)$`, 'ig')))
            for (const file in plan_files) {
              const plan_file_path = plan_dir.concat('/', plan_files[file])
              const plan_file = fs.readFileSync(plan_file_path, 'utf8')
              const plan = plan_file.length > 65000 ? plan_file.toString().substring(0, 65000) + " ..." : plan_file
              const truncated_message = plan_file.length > 65000 ? "Output is too long and was truncated. You can read full Plan in " + run_link + "<br /><br />" : ""
              const output = `
              #### Terraform Plan Validate All 📖: \`${{ steps.plan-validate-all.outcome }}\`
              Plan File: \`${plan_file_path.replace('.txt', '.plan')}\`

              <details><summary>Show Plan</summary>

              \`\`\`\n
              ${plan}
              \`\`\`

              </details>
              ${truncated_message}
              `;

              if (botComment) {
                github.rest.issues.updateComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  comment_id: botComment.id,
                  body: output
                })
              } else {
                github.rest.issues.createComment({
                  issue_number: context.issue.number,
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  body: output
                })
              }
            }
