# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokocli.Release
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli
# PATH: /templates/workflows/universal/auto-release.yml.template
# VERSION: 05.00.00
# BRIEF: Universal build & release � detects platform from manifest.xml
#
# +========================================================================+
# |              UNIVERSAL BUILD & RELEASE PIPELINE                        |
# +========================================================================+
# |                                                                        |
# |  Reads manifest.xml (joomla|dolibarr|generic) to branch logic.       |
# |                                                                        |
# |  Platform-specific:                                                    |
# |    joomla:   XML manifest, type-prefixed packages                      |
# |    dolibarr: mod*.class.php, update.txt, dev version reset             |
# |    generic:  README-only, no update stream                             |
# |                                                                        |
# +========================================================================+

name: "Universal: Build & Release"

on:
  pull_request:
    types: [opened, closed]
    branches:
      - main
  workflow_dispatch:
    inputs:
      action:
        description: 'Action to perform'
        required: false
        type: choice
        default: release
        options:
          - release
          - promote-rc

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
  GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
  GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
  GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}

permissions:
  contents: write

jobs:
  # ── PR Opened → Rename branch to RC and build RC release ─────────────────────
  promote-rc:
    name: Promote to RC
    runs-on: release
    if: >-
      (github.event.action == 'opened' && github.event.pull_request.merged != true) ||
      (github.event_name == 'workflow_dispatch' && inputs.action == 'promote-rc')

    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          token: ${{ secrets.MOKOGITEA_TOKEN }}
          fetch-depth: 1

      - name: Setup mokocli tools
        env:
          MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
          MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
        run: |
          if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
            echo Using pre-installed /opt/mokocli
            echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV
          else
            echo Falling back to fresh clone
            if ! command -v composer > /dev/null 2>&1; then
              sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
            fi
            rm -rf /tmp/mokocli
            CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
            git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
            cd /tmp/mokocli
            composer install --no-dev --no-interaction --quiet
            echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
          fi

      - name: Rename branch to rc
        run: |
          php ${MOKO_CLI}/branch_rename.php \
            --from "${{ github.event.pull_request.head.ref || 'dev' }}" --to rc \
            --token "${{ secrets.MOKOGITEA_TOKEN }}" \
            --api-base "${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" \
            --pr "${{ github.event.pull_request.number }}"

      - name: Checkout rc and configure git
        run: |
          git fetch origin rc
          git checkout rc
          git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
          git config --local user.name "gitea-actions[bot]"
          git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"

      - name: Publish RC release
        run: |
          php ${MOKO_CLI}/release_publish.php \
            --path . --stability rc --bump minor --branch rc \
            --token "${{ secrets.MOKOGITEA_TOKEN }}"

      - name: Update RC release notes from CHANGELOG.md
        run: |
          API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
          TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"

          # Extract [Unreleased] section from changelog
          NOTES=""
          if [ -f "CHANGELOG.md" ]; then
            NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
          fi
          [ -z "$NOTES" ] && NOTES="Release candidate"

          # Find the RC release and update its body
          RELEASE_ID=$(curl -sf -H "Authorization: token ${TOKEN}" \
            "${API_BASE}/releases/tags/release-candidate" \
            | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)

          if [ -n "$RELEASE_ID" ]; then
            python3 -c "
          import json, urllib.request
          body = open('/dev/stdin').read()
          payload = json.dumps({'body': body}).encode()
          req = urllib.request.Request(
              '${API_BASE}/releases/${RELEASE_ID}',
              data=payload, method='PATCH',
              headers={
                  'Authorization': 'token ${TOKEN}',
                  'Content-Type': 'application/json'
              })
          urllib.request.urlopen(req)
          " <<< "$NOTES"
            echo "RC release notes updated from CHANGELOG.md"
          fi

      - name: Summary
        if: always()
        run: |
          echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
          echo "Branch renamed to rc, minor bump, RC release built" >> $GITHUB_STEP_SUMMARY

  # ── Merged PR → Build & Release (or promote RC to stable) ────────────────────
  release:
    name: Build & Release Pipeline
    runs-on: release
    if: >-
      github.event.pull_request.merged == true ||
      (github.event_name == 'workflow_dispatch' && inputs.action != 'promote-rc')

    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          token: ${{ secrets.MOKOGITEA_TOKEN }}
          fetch-depth: 0

      - name: Configure git for bot pushes
        run: |
          git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
          git config --local user.name "gitea-actions[bot]"
          git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"

      - name: Check for merge conflict markers
        run: |
          CONFLICTS=$(grep -rn '<<<<<<< \|>>>>>>> \|^=======$' --include='*.php' --include='*.xml' --include='*.css' --include='*.js' --include='*.json' --include='*.md' --include='*.yml' --include='*.yaml' --include='*.ini' --include='*.txt' . 2>/dev/null | grep -v '.git/' || true)
          if [ -n "$CONFLICTS" ]; then
            echo "::error::Merge conflict markers found — aborting release"
            echo "## Release Blocked: Conflict Markers" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            echo "$CONFLICTS" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            exit 1
          fi
          echo "No conflict markers found"

      - name: Setup mokocli tools
        env:
          MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
          MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
          COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}'
        run: |
          if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
            echo Using pre-installed /opt/mokocli
            echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV
          else
            echo Falling back to fresh clone
            if ! command -v composer > /dev/null 2>&1; then
              sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
            fi
            rm -rf /tmp/mokocli
            CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
            git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
            cd /tmp/mokocli
            composer install --no-dev --no-interaction --quiet
            echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
          fi

      - name: "Detect platform"
        id: platform
        run: |
          php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true
          php ${MOKO_CLI}/manifest_read.php --path . --github-output 2>/dev/null || true

      - name: "Determine version bump level"
        id: bump
        run: |
          # Fix/patch branches: version was already bumped by pre-release, just strip suffix
          # Feature/dev branches: bump minor for the new stable release
          HEAD_REF="${{ github.event.pull_request.head.ref || 'dev' }}"
          case "$HEAD_REF" in
            fix/*|patch/*|hotfix/*|bugfix/*) BUMP="none" ;;
            *)                               BUMP="minor" ;;
          esac
          echo "level=${BUMP}" >> "$GITHUB_OUTPUT"
          echo "Bump level: ${BUMP} (from branch: ${HEAD_REF})"

      - name: "Publish stable release"
        run: |
          BUMP_FLAG=""
          if [ "${{ steps.bump.outputs.level }}" != "none" ]; then
            BUMP_FLAG="--bump ${{ steps.bump.outputs.level }}"
          fi
          php ${MOKO_CLI}/release_publish.php \
            --path . --stability stable ${BUMP_FLAG} --branch main \
            --token "${{ secrets.MOKOGITEA_TOKEN }}"

      - name: "Read published version"
        id: version
        run: |
          VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "")
          VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
          [ -z "$VERSION" ] && VERSION="00.00.00" && echo "skip=true" >> "$GITHUB_OUTPUT"
          echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
          echo "tag=stable" >> "$GITHUB_OUTPUT"
          echo "release_tag=stable" >> "$GITHUB_OUTPUT"
          echo "branch=main" >> "$GITHUB_OUTPUT"
          echo "Published version: ${VERSION}"

      - name: Update release notes and promote changelog
        run: |
          API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
          TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"

          # Get the stable release info (version and ID)
          RELEASE_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \
            "${API_BASE}/releases/tags/stable" 2>/dev/null || echo '{}')
          RELEASE_ID=$(python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" <<< "$RELEASE_JSON" 2>/dev/null || true)
          # Extract version from release name (e.g. "06.17.00" or "v06.17.00")
          VERSION=$(python3 -c "
          import json, sys, re
          r = json.load(sys.stdin)
          name = r.get('name', '')
          m = re.search(r'(\d+\.\d+\.\d+)', name)
          print(m.group(1) if m else '')
          " <<< "$RELEASE_JSON" 2>/dev/null || true)

          # Extract [Unreleased] section from changelog
          NOTES=""
          if [ -f "CHANGELOG.md" ]; then
            NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
          fi
          [ -z "$NOTES" ] && NOTES="Stable release"

          # Update release body via API
          if [ -n "$RELEASE_ID" ]; then
            python3 -c "
          import json, urllib.request
          body = open('/dev/stdin').read()
          payload = json.dumps({'body': body}).encode()
          req = urllib.request.Request(
              '${API_BASE}/releases/${RELEASE_ID}',
              data=payload, method='PATCH',
              headers={
                  'Authorization': 'token ${TOKEN}',
                  'Content-Type': 'application/json'
              })
          urllib.request.urlopen(req)
          " <<< "$NOTES"
            echo "Release notes updated from CHANGELOG.md"
          fi

          # Promote [Unreleased] → [version] in CHANGELOG.md and reset
          if [ -n "$VERSION" ] && [ -f "CHANGELOG.md" ]; then
            DATE=$(date +%Y-%m-%d)
            python3 -c "
          import sys
          version, date = sys.argv[1], sys.argv[2]
          content = open('CHANGELOG.md').read()
          old = '## [Unreleased]'
          new = f'## [Unreleased]\n\n## [{version}] --- {date}'
          content = content.replace(old, new, 1)
          open('CHANGELOG.md', 'w').write(content)
          " "$VERSION" "$DATE"
            git add CHANGELOG.md
            git commit -m "chore: promote changelog [Unreleased] → [${VERSION}]" || true
            git push origin main || true
            echo "Changelog promoted: [Unreleased] → [${VERSION}]"
          fi

      # -- STEP 9: Mirror to GitHub (stable only) --------------------------------
      - name: "Step 9: Mirror release to GitHub"
        if: >-
          steps.version.outputs.skip != 'true' &&
          secrets.GH_MIRROR_TOKEN != ''
        continue-on-error: true
        run: |
          VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
          RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
          GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
          API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
          php ${MOKO_CLI}/release_mirror.php \
            --version "$VERSION" --tag "$RELEASE_TAG" \
            --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
            --gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \
            --branch main 2>&1 || true
          echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY

      # -- STEP 10: Sync main branch to GitHub mirror ----------------------------
      - name: "Step 10: Push main to GitHub mirror"
        if: >-
          steps.version.outputs.skip != 'true' &&
          secrets.GH_MIRROR_TOKEN != ''
        continue-on-error: true
        run: |
          GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
          GH_ORG=$(echo "$GH_REPO" | cut -d/ -f1)
          GH_NAME=$(echo "$GH_REPO" | cut -d/ -f2)
          git remote add github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git" 2>/dev/null || \
            git remote set-url github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git"
          git fetch origin main --depth=1
          git push github origin/main:refs/heads/main --force 2>/dev/null \
            && echo "main branch pushed to GitHub mirror" \
            || echo "WARNING: GitHub mirror push failed"

      - name: "Step 11: Delete rc branch and recreate dev from main"
        if: steps.version.outputs.skip != 'true'
        continue-on-error: true
        run: |
          API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
          TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"

          # Delete rc branch (ephemeral — created by promote-rc)
          curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
            "${API_BASE}/branches/rc" 2>/dev/null \
            && echo "Deleted rc branch" || echo "rc branch not found"

          # Delete dev branch
          curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
            "${API_BASE}/branches/dev" 2>/dev/null && echo "Deleted dev branch"

          # Recreate dev from main (now includes version bump + changelog promotion)
          curl -sf -X POST -H "Authorization: token ${TOKEN}" \
            -H "Content-Type: application/json" \
            "${API_BASE}/branches" \
            -d '{"new_branch_name":"dev","old_branch_name":"main"}' 2>/dev/null && echo "Recreated dev from main"

          echo "Pre-release branches cleaned, dev reset from main" >> $GITHUB_STEP_SUMMARY

      - name: "Step 12: Create version branch from main"
        if: steps.version.outputs.skip != 'true'
        continue-on-error: true
        run: |
          API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
          TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
          VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
          BRANCH_NAME="version/${VERSION}"
          MAIN_SHA=$(git rev-parse HEAD)

          # Delete old version branch if it exists (same version re-release)
          curl -sf -X DELETE -H "Authorization: token ${TOKEN}"             "${API_BASE}/branches/${BRANCH_NAME}" 2>/dev/null && echo "Deleted old ${BRANCH_NAME}"

          # Create version/XX.YY.ZZ from main
          curl -sf -X POST -H "Authorization: token ${TOKEN}"             -H "Content-Type: application/json"             "${API_BASE}/branches"             -d "{\"new_branch_name\":\"${BRANCH_NAME}\",\"old_branch_name\":\"main\"}" 2>/dev/null             && echo "Created ${BRANCH_NAME} from main (${MAIN_SHA})"             || echo "WARNING: ${BRANCH_NAME} creation failed"

          echo "Version branch created: ${BRANCH_NAME} (${MAIN_SHA})" >> $GITHUB_STEP_SUMMARY



      # -- Dolibarr post-release: Reset dev version -----------------------------
      - name: "Post-release: Reset dev version"
        if: steps.version.outputs.skip != 'true'
        continue-on-error: true
        run: |
          API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
          php ${MOKO_CLI}/version_reset_dev.php \
            --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "${API_BASE}" \
            --branch dev --path . 2>&1 || true

      # -- Summary --------------------------------------------------------------
      - name: Pipeline Summary
        if: always()
        run: |
          VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
          PLATFORM="${{ steps.platform.outputs.platform }}"
          if [ "${{ steps.version.outputs.skip }}" = "true" ]; then
            echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY
            echo "No VERSION in README.md" >> $GITHUB_STEP_SUMMARY
          elif [ "${{ steps.check.outputs.already_released }}" = "true" ]; then
            echo "## Already Released — ${VERSION}" >> $GITHUB_STEP_SUMMARY
          else
            echo "" >> $GITHUB_STEP_SUMMARY
            echo "## Build & Release Complete (${PLATFORM})" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
            echo "| Step | Result |" >> $GITHUB_STEP_SUMMARY
            echo "|------|--------|" >> $GITHUB_STEP_SUMMARY
            echo "| Platform | \`${PLATFORM}\` |" >> $GITHUB_STEP_SUMMARY
            echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
            echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY
            echo "| Tag | \`${{ steps.version.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY
            echo "| Release | [View](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY
          fi
