name: Semantic Release
run-name: Semantic Release - ${{ github.ref_name }}

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  PROJECT_NAME: terraform-ingest

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false

permissions:
  contents: write

jobs:
  semantic-release:
    name: Generate Semantic Release Tag
    runs-on: ubuntu-latest
    environment:
      name: production

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

      - name: Set up Git
        run: |
          git config --global user.name "github-actions[bot]"
          git config --global user.email "github-actions[bot]@users.noreply.github.com"

      - name: Get previous tag
        id: prev_tag
        run: |
          PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0")
          echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT

      - name: Parse commits and determine version bump
        id: version
        run: |
          PREV_TAG=${{ steps.prev_tag.outputs.tag }}
          # Remove 'v' prefix if present
          PREV_VERSION="${PREV_TAG#v}"
          
          # Get commits since last tag
          if git rev-parse "${{ steps.prev_tag.outputs.tag }}" >/dev/null 2>&1; then
            COMMITS=$(git log "${{ steps.prev_tag.outputs.tag }}..HEAD" --pretty=format:%s)
          else
            COMMITS=$(git log --pretty=format:%s)
          fi
          
          echo "Commits since last release:"
          echo "$COMMITS"
          
          # Determine version bump based on commit messages
          # Look for conventional commit prefixes
          MAJOR_BUMP=0
          MINOR_BUMP=0
          PATCH_BUMP=0
          
          echo "$COMMITS" | while IFS= read -r line; do
            if [[ "$line" =~ ^BREAKING\ CHANGE|^feat\!: ]]; then
              MAJOR_BUMP=1
            elif [[ "$line" =~ ^feat: ]]; then
              MINOR_BUMP=1
            elif [[ "$line" =~ ^fix:|^refactor:|^perf: ]]; then
              PATCH_BUMP=1
            fi
          done
          
          if [[ "$COMMITS" =~ BREAKING\ CHANGE|feat\!: ]]; then
            MAJOR_BUMP=1
          elif [[ "$COMMITS" =~ feat: ]]; then
            MINOR_BUMP=1
          elif [[ "$COMMITS" =~ fix:|refactor:|perf: ]]; then
            PATCH_BUMP=1
          fi
          
          # Parse version
          IFS='.' read -r MAJOR MINOR PATCH <<< "$PREV_VERSION"
          MAJOR=${MAJOR:-0}
          MINOR=${MINOR:-0}
          PATCH=${PATCH:-0}
          
          # Bump version
          if [[ $MAJOR_BUMP -eq 1 ]]; then
            MAJOR=$((MAJOR + 1))
            MINOR=0
            PATCH=0
          elif [[ $MINOR_BUMP -eq 1 ]]; then
            MINOR=$((MINOR + 1))
            PATCH=0
          elif [[ $PATCH_BUMP -eq 1 ]] || git rev-parse "${{ steps.prev_tag.outputs.tag }}" >/dev/null 2>&1 && [[ "$PREV_TAG" != "0.0.0" ]]; then
            PATCH=$((PATCH + 1))
          else
            # If no semantic commits found and no previous tag, make it 0.0.1
            if [[ "$PREV_TAG" == "0.0.0" ]] && [[ $PATCH_BUMP -eq 0 ]] && [[ $MINOR_BUMP -eq 0 ]] && [[ $MAJOR_BUMP -eq 0 ]]; then
              PATCH=1
            fi
          fi
          
          NEW_VERSION="$MAJOR.$MINOR.$PATCH"
          echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
          echo "New version: $NEW_VERSION"

      - name: Check if tag already exists
        id: check_tag
        run: |
          if git rev-parse "${{ steps.version.outputs.new_version }}" >/dev/null 2>&1; then
            echo "tag_exists=true" >> $GITHUB_OUTPUT
            echo "Tag ${{ steps.version.outputs.new_version }} already exists"
          else
            echo "tag_exists=false" >> $GITHUB_OUTPUT
          fi

      - name: Create and push tag
        if: steps.check_tag.outputs.tag_exists == 'false'
        run: |
          git tag -a "${{ steps.version.outputs.new_version }}" -m "Release ${{ steps.version.outputs.new_version }}"
          git push origin "${{ steps.version.outputs.new_version }}"
          echo "Created and pushed tag: ${{ steps.version.outputs.new_version }}"

      - name: Create Release Notes
        if: steps.check_tag.outputs.tag_exists == 'false'
        id: release_notes
        run: |
          PREV_TAG=${{ steps.prev_tag.outputs.tag }}
          NEW_VERSION="${{ steps.version.outputs.new_version }}"
          
          if git rev-parse "$PREV_TAG" >/dev/null 2>&1; then
            CHANGELOG=$(git log "$PREV_TAG..HEAD" --pretty=format:"- %s (%h)")
          else
            CHANGELOG=$(git log --pretty=format:"- %s (%h)")
          fi
          
          echo "changelog<<EOF" >> $GITHUB_OUTPUT
          echo "$CHANGELOG" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Create GitHub Release
        if: steps.check_tag.outputs.tag_exists == 'false'
        uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
        with:
          tag_name: ${{ steps.version.outputs.new_version }}
          name: Release ${{ steps.version.outputs.new_version }}
          body: |
            ## What's Changed
            
            ${{ steps.release_notes.outputs.changelog }}

            **Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.prev_tag.outputs.tag }}...${{ steps.version.outputs.new_version }}
          draft: false
          prerelease: false

      - name: Log Output
        run: |
          echo "Previous tag: ${{ steps.prev_tag.outputs.tag }}"
          echo "New version: ${{ steps.version.outputs.new_version }}"
          echo "Tag exists: ${{ steps.check_tag.outputs.tag_exists }}"
