name: Macro Release (Reusable)

# Reusable workflow for releasing individual FreeCAD macros
# Called by component-specific workflows with appropriate inputs

on:
  workflow_dispatch:
    inputs:
      tag_prefix:
        description: 'Tag prefix to match (e.g., macro-cut-object-for-magnets-v)'
        required: true
        type: string
      macro_dir:
        description: 'Macro directory relative to macros/ (e.g., Cut_Object_for_Magnets)'
        required: true
        type: string
      macro_file:
        description: 'Main macro filename (e.g., CutObjectForMagnets.FCMacro)'
        required: true
        type: string
      macro_name:
        description: 'Human-readable macro name (e.g., Cut Object for Magnets)'
        required: true
        type: string
      archive_name:
        description: 'Archive base name (e.g., CutObjectForMagnets)'
        required: true
        type: string
      readme_file:
        description: 'README filename (e.g., README-CutObjectForMagnets.md)'
        required: true
        type: string
      wiki_url:
        description: 'FreeCAD Wiki URL for this macro'
        required: false
        type: string
        default: ''
      description:
        description: 'Short description for release notes'
        required: true
        type: string
  workflow_call:
    inputs:
      tag_prefix:
        description: 'Tag prefix to match (e.g., macro-cut-object-for-magnets-v)'
        required: true
        type: string
      macro_dir:
        description: 'Macro directory relative to macros/ (e.g., Cut_Object_for_Magnets)'
        required: true
        type: string
      macro_file:
        description: 'Main macro filename (e.g., CutObjectForMagnets.FCMacro)'
        required: true
        type: string
      macro_name:
        description: 'Human-readable macro name (e.g., Cut Object for Magnets)'
        required: true
        type: string
      archive_name:
        description: 'Archive base name (e.g., CutObjectForMagnets)'
        required: true
        type: string
      readme_file:
        description: 'README filename (e.g., README-CutObjectForMagnets.md)'
        required: true
        type: string
      wiki_url:
        description: 'FreeCAD Wiki URL for this macro'
        required: false
        type: string
        default: ''
      description:
        description: 'Short description for release notes'
        required: true
        type: string

jobs:
  validate-and-release:
    name: Validate Tag and Create Release
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Validate semantic version tag
        id: version
        env:
          TAG_PREFIX: ${{ inputs.tag_prefix }}
        run: |
          TAG="${GITHUB_REF#refs/tags/}"
          echo "tag=$TAG" >> "$GITHUB_OUTPUT"

          # Build regex pattern from tag prefix
          PATTERN="^${TAG_PREFIX}([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?)\$"

          if [[ ! "$TAG" =~ $PATTERN ]]; then
              echo "ERROR: Tag '$TAG' does not match expected format (${TAG_PREFIX}X.Y.Z)"
              exit 1
          fi

          VERSION="${BASH_REMATCH[1]}"
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"

          # Check if this is a prerelease
          if [[ "$VERSION" =~ -[a-zA-Z0-9.]+ ]]; then
              echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
          else
              echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
          fi

          echo "Parsed version: $VERSION"

      - name: Verify macro version in files
        env:
          VERSION: ${{ steps.version.outputs.version }}
          MACRO_DIR: ${{ inputs.macro_dir }}
          MACRO_FILE: ${{ inputs.macro_file }}
          MACRO_NAME: ${{ inputs.macro_name }}
        run: |
          MACRO_PATH="macros/${MACRO_DIR}/${MACRO_FILE}"

          echo "Verifying version in source files matches tag: $VERSION"

          # Check __Version__ in .FCMacro file
          if [ -f "$MACRO_PATH" ]; then
              MACRO_VERSION=$(grep -o '__Version__ = "[^"]*"' "$MACRO_PATH" | cut -d'"' -f2)
              if [ "$MACRO_VERSION" != "$VERSION" ]; then
                  echo "ERROR: Version mismatch in $MACRO_PATH"
                  echo "  Expected: $VERSION"
                  echo "  Found:    $MACRO_VERSION"
                  echo ""
                  echo "The version in source files must be updated before tagging."
                  echo "Run the appropriate bump command first."
                  exit 1
              fi
              echo "✓ $MACRO_PATH: $MACRO_VERSION"
          else
              echo "ERROR: Macro file not found: $MACRO_PATH"
              exit 1
          fi

          # Check package.xml
          PKG_VERSION=$(awk -v name="$MACRO_NAME" '
              /<macro>/ { in_macro=1 }
              /<\/macro>/ { in_macro=0; found_name=0 }
              in_macro && index($0, name) > 0 { found_name=1 }
              in_macro && found_name && /<version>/ {
                  gsub(/.*<version>/, ""); gsub(/<\/version>.*/, ""); print; exit
              }
          ' package.xml)
          if [ "$PKG_VERSION" != "$VERSION" ]; then
              echo "ERROR: Version mismatch in package.xml ($MACRO_NAME section)"
              echo "  Expected: $VERSION"
              echo "  Found:    $PKG_VERSION"
              exit 1
          fi
          echo "✓ package.xml ($MACRO_NAME): $PKG_VERSION"

          echo ""
          echo "Version verification passed!"

      - name: Create macro archive
        env:
          VERSION: ${{ steps.version.outputs.version }}
          MACRO_DIR: ${{ inputs.macro_dir }}
          MACRO_FILE: ${{ inputs.macro_file }}
          ARCHIVE_NAME: ${{ inputs.archive_name }}
          README_FILE: ${{ inputs.readme_file }}
        run: |
          # Create staging directory
          mkdir -p "staging/${ARCHIVE_NAME}-${VERSION}"

          # Copy macro files
          cp "macros/${MACRO_DIR}/${MACRO_FILE}" "staging/${ARCHIVE_NAME}-${VERSION}/"

          # Copy icon if exists
          for ext in svg png; do
              ICON_FILE="macros/${MACRO_DIR}/${ARCHIVE_NAME}.${ext}"
              if [ -f "$ICON_FILE" ]; then
                  cp "$ICON_FILE" "staging/${ARCHIVE_NAME}-${VERSION}/"
              fi
          done

          # Copy README
          if [ -f "macros/${MACRO_DIR}/${README_FILE}" ]; then
              cp "macros/${MACRO_DIR}/${README_FILE}" "staging/${ARCHIVE_NAME}-${VERSION}/README.md"
          fi

          # Copy LICENSE
          cp LICENSE "staging/${ARCHIVE_NAME}-${VERSION}/"

          # Create tar.gz archive
          cd staging
          tar -czvf "${ARCHIVE_NAME}-${VERSION}.tar.gz" "${ARCHIVE_NAME}-${VERSION}"

          # Create zip archive
          zip -r "${ARCHIVE_NAME}-${VERSION}.zip" "${ARCHIVE_NAME}-${VERSION}"

          mv "${ARCHIVE_NAME}-${VERSION}.tar.gz" ../
          mv "${ARCHIVE_NAME}-${VERSION}.zip" ../
          cd ..

          echo "Created archives:"
          ls -la "${ARCHIVE_NAME}-${VERSION}."*

      - name: Extract changelog section
        id: changelog
        env:
          VERSION: ${{ steps.version.outputs.version }}
          MACRO_NAME: ${{ inputs.macro_name }}
          DESCRIPTION: ${{ inputs.description }}
          MACRO_FILE: ${{ inputs.macro_file }}
          MACRO_DIR: ${{ inputs.macro_dir }}
          README_FILE: ${{ inputs.readme_file }}
          WIKI_URL: ${{ inputs.wiki_url }}
        run: |
          # Match header exactly as it appears in CHANGELOG.md
          HEADER="### ${MACRO_NAME} Macro v${VERSION}"

          # Extract section between this version header and the next component header or separator
          # Only exit on: "---" separator OR "### " followed by component name (capital letter)
          # This allows #### Added, #### Changed, etc. to be included
          CHANGELOG_CONTENT=$(awk -v header="$HEADER" '
              BEGIN { found=0 }
              $0 == header || $0 == header " " { found=1; next }
              found && /^---$/ { exit }
              found && /^### [A-Z]/ { exit }
              found { print }
          ' CHANGELOG.md)

          # Build release body
          cat > release_body.md << EOF
          ## ${MACRO_NAME} Macro v${VERSION}

          ${DESCRIPTION}

          ### Installation

          Copy \`${MACRO_FILE}\` to your FreeCAD macro directory:

          - **macOS**: \`~/Library/Application Support/FreeCAD/Macro/\`
          - **Linux**: \`~/.local/share/FreeCAD/Macro/\`
          - **Windows**: \`%APPDATA%/FreeCAD/Macro/\`

          Optionally copy the icon file (\`.svg\` or \`.png\`) to the same location.

          ### Documentation

          - [Full README](https://github.com/spkane/freecad-robust-mcp-and-more/blob/main/macros/${MACRO_DIR}/${README_FILE})
          EOF

          if [ -n "$WIKI_URL" ]; then
              echo "- [FreeCAD Wiki Page](${WIKI_URL})" >> release_body.md
          fi

          if [ -n "$CHANGELOG_CONTENT" ]; then
              {
                  echo ""
                  echo "### Changelog"
                  echo ""
                  echo "$CHANGELOG_CONTENT"
              } >> release_body.md
          fi

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          name: "${{ inputs.macro_name }} Macro v${{ steps.version.outputs.version }}"
          tag_name: ${{ github.ref_name }}
          prerelease: ${{ steps.version.outputs.is_prerelease == 'true' }}
          generate_release_notes: true
          body_path: release_body.md
          files: |
            ${{ inputs.archive_name }}-${{ steps.version.outputs.version }}.tar.gz
            ${{ inputs.archive_name }}-${{ steps.version.outputs.version }}.zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Generate summary
        env:
          VERSION: ${{ steps.version.outputs.version }}
          MACRO_NAME: ${{ inputs.macro_name }}
          ARCHIVE_NAME: ${{ inputs.archive_name }}
        run: |
          {
            echo "## ${MACRO_NAME} Macro Release"
            echo ""
            echo "**Version:** ${VERSION}"
            echo ""
            echo "### Downloads"
            echo ""
            echo "- \`${ARCHIVE_NAME}-${VERSION}.tar.gz\`"
            echo "- \`${ARCHIVE_NAME}-${VERSION}.zip\`"
          } >> "$GITHUB_STEP_SUMMARY"
