name: Release

on:
  push:
    branches: [master]
  workflow_dispatch:

permissions:
  contents: write

jobs:
  release:
    name: Create Release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          submodules: recursive

      - name: Check for src/ changes
        id: changes
        env:
          BEFORE: ${{ github.event.before }}
        run: |
          if [ -z "$BEFORE" ] || [ "$BEFORE" = "0000000000000000000000000000000000000000" ]; then
            echo "src_changed=true" >> "$GITHUB_OUTPUT"
          else
            CHANGED=$(git diff --name-only "$BEFORE" HEAD -- 'src/' | wc -l)
            [ "$CHANGED" -gt 0 ] && echo "src_changed=true" >> "$GITHUB_OUTPUT" || echo "src_changed=false" >> "$GITHUB_OUTPUT"
          fi

      - name: Read version
        if: steps.changes.outputs.src_changed == 'true'
        id: version
        run: |
          VERSION=$(grep -oP '(?<=<Version>)[^<]+' src/Directory.Build.props)
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"
          echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"

      - name: Check if release exists
        if: steps.changes.outputs.src_changed == 'true'
        id: check_release
        run: |
          if gh release view "${{ steps.version.outputs.tag }}" &>/dev/null; then
            echo "exists=true" >> "$GITHUB_OUTPUT"
          else
            echo "exists=false" >> "$GITHUB_OUTPUT"
          fi
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup .NET 10
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '10.0.x'

      - name: Publish Server win-x64
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: dotnet publish src/EchoHub.Server/EchoHub.Server.csproj -c Release -r win-x64 --self-contained true -o publish/server-win-x64

      - name: Publish Server linux-x64
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: dotnet publish src/EchoHub.Server/EchoHub.Server.csproj -c Release -r linux-x64 --self-contained true -o publish/server-linux-x64

      - name: Publish Server osx-x64
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: dotnet publish src/EchoHub.Server/EchoHub.Server.csproj -c Release -r osx-x64 --self-contained true -o publish/server-osx-x64

      - name: Publish Server osx-arm64
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: dotnet publish src/EchoHub.Server/EchoHub.Server.csproj -c Release -r osx-arm64 --self-contained true -o publish/server-osx-arm64

      - name: Publish Client win-x64
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: dotnet publish src/EchoHub.Client/EchoHub.Client.csproj -c Release -r win-x64 --self-contained true -o publish/client-win-x64

      - name: Publish Client linux-x64
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: dotnet publish src/EchoHub.Client/EchoHub.Client.csproj -c Release -r linux-x64 --self-contained true -o publish/client-linux-x64

      - name: Publish Client osx-x64
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: dotnet publish src/EchoHub.Client/EchoHub.Client.csproj -c Release -r osx-x64 --self-contained true -o publish/client-osx-x64

      - name: Publish Client osx-arm64
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: dotnet publish src/EchoHub.Client/EchoHub.Client.csproj -c Release -r osx-arm64 --self-contained true -o publish/client-osx-arm64

      - name: Zip artifacts
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: |
          cd publish
          zip -r ../EchoHub-Server-win-x64.zip server-win-x64/
          zip -r ../EchoHub-Server-linux-x64.zip server-linux-x64/
          zip -r ../EchoHub-Server-osx-x64.zip server-osx-x64/
          zip -r ../EchoHub-Server-osx-arm64.zip server-osx-arm64/
          zip -r ../EchoHub-Client-win-x64.zip client-win-x64/
          zip -r ../EchoHub-Client-linux-x64.zip client-linux-x64/
          zip -r ../EchoHub-Client-osx-x64.zip client-osx-x64/
          zip -r ../EchoHub-Client-osx-arm64.zip client-osx-arm64/

      - name: Build release notes
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        id: notes
        run: |
          TAG="${{ steps.version.outputs.tag }}"
          CHANGELOG_URL="https://huebyte.github.io/EchoHub/changelog/${TAG}.html"
          REPO="https://github.com/${{ github.repository }}"
          PREV_TAG=$(git tag --sort=-v:refname | grep -v "^${TAG}$" | head -n 1)

          {
            echo "body<<RELEASE_EOF"
            echo "📋 **[Full Changelog](${CHANGELOG_URL})**"
            echo ""
            echo "---"
            echo ""
            echo "### Commits"
            echo ""
            if [ -n "$PREV_TAG" ]; then
              git log "${PREV_TAG}..HEAD" --pretty=format:"- %s (%h)" --no-merges
            else
              git log HEAD --pretty=format:"- %s (%h)" --no-merges
            fi
            echo ""
            echo ""
            if [ -n "$PREV_TAG" ]; then
              echo "*Version diff: [${PREV_TAG}...${TAG}](${REPO}/compare/${PREV_TAG}...${TAG})*"
            else
              echo "*Version diff: [${TAG}](${REPO}/commits/${TAG})*"
            fi
            echo "RELEASE_EOF"
          } >> "$GITHUB_OUTPUT"

      - name: Create GitHub Release
        if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
        run: |
          gh release create "${{ steps.version.outputs.tag }}" \
            --title "EchoHub ${{ steps.version.outputs.tag }}" \
            --notes "${{ steps.notes.outputs.body }}" \
            EchoHub-Server-win-x64.zip \
            EchoHub-Server-linux-x64.zip \
            EchoHub-Server-osx-x64.zip \
            EchoHub-Server-osx-arm64.zip \
            EchoHub-Client-win-x64.zip \
            EchoHub-Client-linux-x64.zip \
            EchoHub-Client-osx-x64.zip \
            EchoHub-Client-osx-arm64.zip
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
