################################################################################
# nightly-drift.yml — sample GitHub Actions workflow for nightly drift
# detection on the bookstore-platform Terraform tree.
#
# Copy this to .github/workflows/ in YOUR repository. Adjust paths, region,
# role ARN to match your setup.
#
# What it does:
#   - Runs every night at 03:00 UTC (cron '0 3 * * *').
#   - Runs `terraform plan -detailed-exitcode`.
#   - Exit code 0 = no drift. Exit code 2 = drift detected.
#   - On exit code 2, opens a GitHub issue with the plan output.
#
# Why nightly? Drift accumulates from console actions, out-of-band Terraform
# runs, IAM-policy auto-rotation, EBS auto-grow, ASG re-creations after
# instance failures. You want to catch it before the next deploy compounds it.
################################################################################

name: terraform-drift-check

on:
  schedule:
    # 03:00 UTC daily. Tune to a low-traffic window for your team.
    - cron: '0 3 * * *'
  workflow_dispatch:
    # Allow manual triggering via the Actions tab.

permissions:
  id-token: write
  contents: read
  issues: write

env:
  TF_VERSION: '1.10.5'
  WORKING_DIR: 'examples/bookstore-platform/terraform'

jobs:
  drift-check:
    name: terraform plan (drift check)
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ${{ env.WORKING_DIR }}

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: ${{ env.TF_VERSION }}

      - name: Configure AWS credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ${{ vars.AWS_REGION || 'ap-south-1' }}
          audience: sts.amazonaws.com

      - name: terraform init
        run: terraform init -input=false

      - name: terraform plan -detailed-exitcode
        id: plan
        run: |
          set +e
          terraform plan -input=false -detailed-exitcode -no-color -out=drift.tfplan > plan_output.txt 2>&1
          echo "exit_code=$?" >> $GITHUB_OUTPUT
          cat plan_output.txt
        continue-on-error: true

      - name: Open or update drift issue (dedup by label)
        if: steps.plan.outputs.exit_code == '2'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const planOutput = fs.readFileSync('${{ env.WORKING_DIR }}/plan_output.txt', 'utf8');
            const trimmed = planOutput.length > 60000
              ? planOutput.slice(0, 60000) + '\n\n[...truncated...]'
              : planOutput;

            const today = new Date().toISOString().slice(0, 10);
            const body = [
              '## Terraform drift detected',
              '',
              `Detection run: ${today}`,
              '',
              'The nightly drift check found differences between the configured',
              'state (`*.tf` files) and the actual AWS resources.',
              '',
              'See `DRIFT.md` for the runbook.',
              '',
              '<details><summary>terraform plan output</summary>',
              '',
              '```hcl',
              trimmed,
              '```',
              '',
              '</details>',
            ].join('\n');

            // Dedup: look for an existing open issue with the `drift-detected`
            // label. If one exists, append a dated comment instead of opening
            // a new issue (keeps the issue list signal-to-noise high).
            const existing = await github.paginate(
              github.rest.issues.listForRepo,
              {
                owner: context.repo.owner,
                repo:  context.repo.repo,
                state: 'open',
                labels: 'drift-detected',
                per_page: 100,
              },
            );

            if (existing.length > 0) {
              const issue = existing[0];
              console.log(`Updating existing drift issue #${issue.number}`);
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo:  context.repo.repo,
                issue_number: issue.number,
                body,
              });
            } else {
              console.log('Creating new drift issue');
              await github.rest.issues.create({
                owner: context.repo.owner,
                repo:  context.repo.repo,
                title: `Drift detected on ${today}`,
                body,
                labels: ['drift-detected', 'terraform', 'ops'],
              });
            }

      - name: Fail the job on drift
        if: steps.plan.outputs.exit_code == '2'
        run: |
          echo "Drift detected. Issue opened."
          exit 1

      - name: Fail the job on plan error
        if: steps.plan.outputs.exit_code != '0' && steps.plan.outputs.exit_code != '2'
        run: |
          echo "terraform plan failed (exit code ${{ steps.plan.outputs.exit_code }})."
          exit 1
