name: Release Trigger

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to release (e.g., 0.1.11). Leave empty to auto-increment patch version.'
        required: false
        type: string

jobs:
  bump-version:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
        with:
          fetch-depth: 0
          token: ${{ secrets.RELEASE_PAT }}

      - name: Configure Git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

      - name: Determine version
        id: version
        env:
          INPUT_VERSION: ${{ github.event.inputs.version }}
        run: |
          if [[ -n "$INPUT_VERSION" ]]; then
            # Manual version specified - strip optional v prefix
            VERSION="${INPUT_VERSION#v}"
            # Validate strict semver format to prevent injection
            if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
              echo "Error: Invalid version format '$VERSION'. Must be X.Y.Z (e.g. 1.2.3 or v1.2.3)"
              exit 1
            fi
            echo "version=$VERSION" >> $GITHUB_OUTPUT
            echo "tag=v$VERSION" >> $GITHUB_OUTPUT
            echo "Using manual version: $VERSION"
          else
            # Auto-increment patch version
            LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
            echo "Latest tag: $LATEST_TAG"

            # Extract version number and increment
            VERSION=$(echo $LATEST_TAG | sed 's/v//')
            IFS='.' read -ra VERSION_PARTS <<< "$VERSION"
            MAJOR=${VERSION_PARTS[0]:-0}
            MINOR=${VERSION_PARTS[1]:-0}
            PATCH=${VERSION_PARTS[2]:-0}

            # Increment patch version
            PATCH=$((PATCH + 1))
            NEW_VERSION="$MAJOR.$MINOR.$PATCH"

            echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
            echo "tag=v$NEW_VERSION" >> $GITHUB_OUTPUT
            echo "Auto-incremented version: $NEW_VERSION"
          fi

      - name: Check if tag already exists
        run: |
          if git rev-parse "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
            echo "Error: Tag ${{ steps.version.outputs.tag }} already exists!"
            exit 1
          fi

      - name: Create release branch
        run: |
          BRANCH="chore/release-${{ steps.version.outputs.tag }}"
          git checkout -b "$BRANCH"
          echo "branch=$BRANCH" >> $GITHUB_ENV

      - name: Update pyproject.toml
        run: |
          sed -i "s/version = \".*\"/version = \"${{ steps.version.outputs.version }}\"/" pyproject.toml
          echo "Updated pyproject.toml to version ${{ steps.version.outputs.version }}"

      - name: Update CHANGELOG.md
        run: |
          if [ -f "CHANGELOG.md" ]; then
            DATE=$(date +%Y-%m-%d)

            # Get the previous tag by sorting all version tags numerically
            # (git describe --tags only finds tags reachable from HEAD,
            #  which misses tags on unmerged release branches)
            PREVIOUS_TAG=$(git tag -l 'v*' --sort=-version:refname | head -n 1)

            echo "Generating changelog from commits..."
            if [[ -n "$PREVIOUS_TAG" ]]; then
              echo "Changes since $PREVIOUS_TAG"
              COMMITS=$(git log --oneline "$PREVIOUS_TAG"..HEAD --no-merges --pretty=format:"- %s" 2>/dev/null || echo "- Initial release")
            else
              echo "No previous tag found - this is the first release"
              COMMITS="- Initial release"
            fi

            # Create new changelog entry — insert after the marker comment
            NEW_ENTRY=$(printf '%s\n' \
              "" \
              "## [${{ steps.version.outputs.version }}] - $DATE" \
              "" \
              "### Changed" \
              "" \
              "$COMMITS")

            awk -v entry="$NEW_ENTRY" '/<!-- insert new changelog below this comment -->/ { print; print entry; next } {print}' CHANGELOG.md > CHANGELOG.md.tmp
            mv CHANGELOG.md.tmp CHANGELOG.md

            echo "✅ Updated CHANGELOG.md with commits since $PREVIOUS_TAG"
          else
            echo "No CHANGELOG.md found"
          fi

      - name: Commit version bump
        run: |
          if [ -f "CHANGELOG.md" ]; then
            git add pyproject.toml CHANGELOG.md
          else
            git add pyproject.toml
          fi

          if git diff --cached --quiet; then
            echo "No changes to commit"
          else
            git commit -m "chore: bump version to ${{ steps.version.outputs.version }}"
            echo "Changes committed"
          fi

      - name: Create and push tag
        run: |
          git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}"
          git push origin "${{ env.branch }}"
          git push origin "${{ steps.version.outputs.tag }}"
          echo "Branch ${{ env.branch }} and tag ${{ steps.version.outputs.tag }} pushed"

      - name: Bump to dev version
        id: dev_version
        run: |
          IFS='.' read -r MAJOR MINOR PATCH <<< "${{ steps.version.outputs.version }}"
          NEXT_DEV="$MAJOR.$MINOR.$((PATCH + 1)).dev0"
          echo "dev_version=$NEXT_DEV" >> $GITHUB_OUTPUT
          sed -i "s/version = \".*\"/version = \"$NEXT_DEV\"/" pyproject.toml
          git add pyproject.toml
          if git diff --cached --quiet; then
            echo "No dev version changes to commit"
          else
            git commit -m "chore: begin $NEXT_DEV development"
            git push origin "${{ env.branch }}"
            echo "Bumped to dev version $NEXT_DEV"
          fi

      - name: Open pull request
        env:
          GITHUB_TOKEN: ${{ secrets.RELEASE_PAT }}
        run: |
          gh pr create \
            --base main \
            --head "${{ env.branch }}" \
            --title "chore: release ${{ steps.version.outputs.version }}, begin ${{ steps.dev_version.outputs.dev_version }} development" \
            --body "Automated release of ${{ steps.version.outputs.version }}.

          This PR was created by the Release Trigger workflow. The git tag \`${{ steps.version.outputs.tag }}\` has already been pushed and the release artifacts are being built.

          Merging this PR will set \`main\` to \`${{ steps.dev_version.outputs.dev_version }}\` so that development installs are clearly marked as pre-release."

      - name: Summary
        run: |
          echo "✅ Version bumped to ${{ steps.version.outputs.version }}"
          echo "✅ Tag ${{ steps.version.outputs.tag }} created and pushed"
          echo "✅ Dev version set to ${{ steps.dev_version.outputs.dev_version }}"
          echo "✅ PR opened to merge version bump into main"
          echo "🚀 Release workflow is building artifacts from the tag"
