# Все корни Terraform в environments/dev/<имя>/ (файл main.tf).
# State на диске раннера: /var/lib/terraform-state/grafana-dev/<имя>/terraform.tfstate
# (без S3; один persistent path на хосте act_runner).

name: terraform-dev

on:
  pull_request:
    paths:
      - "environments/dev/**"
      - "environments/modules/**"
      - ".gitea/workflows/terraform-dev.yml"
  push:
    branches:
      - main
    paths:
      - "environments/dev/**"
      - "environments/modules/**"
      - ".gitea/workflows/terraform-dev.yml"
  workflow_dispatch:
    inputs:
      run_apply:
        description: "Run terraform apply (true/false)"
        required: true
        default: "false"

env:
  TF_IN_AUTOMATION: "true"
  TF_INPUT: "false"
  TF_CLI_ARGS_init: "-backend=false -plugin-dir=/root/.terraform.d/plugins"
  STATE_ROOT: "/var/lib/terraform-state/grafana-dev"

jobs:
  validate:
    runs-on: [terraform-host]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Terraform version
        run: terraform version

      - name: Terraform fmt check
        run: terraform fmt -check -recursive

      - name: Terraform init + validate (all dev environments)
        env:
          VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
          VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
        run: |
          set -euo pipefail
          restore_state() {
            local dir="$1"
            local name="${dir%/}"
            name="${name##*/}"
            local sdir="${STATE_ROOT}/${name}"
            mkdir -p "$sdir"
            if [ -f "${sdir}/terraform.tfstate" ]; then
              cp -f "${sdir}/terraform.tfstate" "${dir}/terraform.tfstate"
              echo "Restored state: ${sdir} -> ${dir}"
            else
              echo "No saved state yet: ${sdir}"
            fi
          }
          found=0
          for d in environments/dev/*/; do
            [ -f "${d}main.tf" ] || continue
            found=1
            echo "========== ${d} =========="
            restore_state "$d"
            (cd "$d" && terraform init && terraform validate)
          done
          if [ "$found" -eq 0 ]; then
            echo "No environments found under environments/dev/*/ with main.tf"
            exit 1
          fi

  plan:
    needs: validate
    runs-on: [terraform-host]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Terraform plan (all dev environments)
        env:
          VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
          VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
        run: |
          set -euo pipefail
          restore_state() {
            local dir="$1"
            local name="${dir%/}"
            name="${name##*/}"
            local sdir="${STATE_ROOT}/${name}"
            mkdir -p "$sdir"
            if [ -f "${sdir}/terraform.tfstate" ]; then
              cp -f "${sdir}/terraform.tfstate" "${dir}/terraform.tfstate"
              echo "Restored state: ${sdir} -> ${dir}"
            else
              echo "No saved state yet: ${sdir}"
            fi
          }
          found=0
          for d in environments/dev/*/; do
            [ -f "${d}main.tf" ] || continue
            found=1
            echo "========== ${d} =========="
            restore_state "$d"
            (cd "$d" && terraform init && terraform plan -refresh=false -lock=false -out=tfplan)
          done
          if [ "$found" -eq 0 ]; then
            echo "No environments found under environments/dev/*/ with main.tf"
            exit 1
          fi

  apply:
    if: github.event_name == 'workflow_dispatch' && github.event.inputs.run_apply == 'true'
    needs: plan
    runs-on: [terraform-host]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Terraform apply (all dev environments)
        env:
          VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
          VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
        run: |
          set -euo pipefail
          restore_state() {
            local dir="$1"
            local name="${dir%/}"
            name="${name##*/}"
            local sdir="${STATE_ROOT}/${name}"
            mkdir -p "$sdir"
            if [ -f "${sdir}/terraform.tfstate" ]; then
              cp -f "${sdir}/terraform.tfstate" "${dir}/terraform.tfstate"
              echo "Restored state: ${sdir} -> ${dir}"
            else
              echo "No saved state yet: ${sdir}"
            fi
          }
          save_state() {
            local dir="$1"
            local name="${dir%/}"
            name="${name##*/}"
            local sdir="${STATE_ROOT}/${name}"
            mkdir -p "$sdir"
            if [ -f "${dir}/terraform.tfstate" ]; then
              cp -f "${dir}/terraform.tfstate" "${sdir}/terraform.tfstate"
              chmod 600 "${sdir}/terraform.tfstate" 2>/dev/null || true
              echo "Saved state: ${dir} -> ${sdir}"
            fi
          }
          found=0
          for d in environments/dev/*/; do
            [ -f "${d}main.tf" ] || continue
            found=1
            echo "========== ${d} =========="
            restore_state "$d"
            rc=0
            (cd "$d" && terraform init && terraform apply -refresh=false -lock=false -auto-approve) || rc=$?
            save_state "$d"
            [ "$rc" -eq 0 ] || exit "$rc"
          done
          if [ "$found" -eq 0 ]; then
            echo "No environments found under environments/dev/*/ with main.tf"
            exit 1
          fi
