name: Release Build

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to release (e.g. 5.1.1). Must match an existing tag vX.Y.Z.'
        required: true
      create_release:
        description: 'Create/update GitHub release with artifacts?'
        type: boolean
        default: true

permissions:
  contents: write

jobs:
  build-macos-app:
    runs-on: macos-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Get version from tag
        id: get_version
        run: |
          if [[ -n "${{ inputs.version }}" ]]; then
            VERSION="${{ inputs.version }}"
          elif [[ "$GITHUB_REF" == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
          else
            VERSION="5.1.1"
          fi
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"

      - name: Export version to env
        run: |
          echo "SCIDCOMMUNITY_VERSION=${{ steps.get_version.outputs.version }}" >> "$GITHUB_ENV"

      - name: Build macOS app bundle
        run: |
          bash build_app.sh
          make install

      - name: Create macOS ZIP
        run: |
          ditto -c -k --sequesterRsrc --keepParent ScidCommunity.app scidCommunity-macos.zip

      - name: Upload macOS artifact
        uses: actions/upload-artifact@v7
        with:
          name: scidCommunity-macos
          path: scidCommunity-macos.zip
  build-windows:
    runs-on: windows-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Get version from tag
        id: get_version
        shell: bash
        run: |
          if [[ -n "${{ inputs.version }}" ]]; then
            VERSION="${{ inputs.version }}"
          elif [[ $GITHUB_REF == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
          else
            VERSION="5.1.1"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Export version to env
        shell: bash
        run: |
          echo "SCIDCOMMUNITY_VERSION=${{ steps.get_version.outputs.version }}" >> $GITHUB_ENV

      - name: Setup MSVC
        uses: microsoft/setup-msbuild@v3

      - name: Build Tcl library
        shell: cmd
        run: |
          mkdir tcltk
          cd tcltk
          git clone --depth=1 --branch core-8-6-15 https://github.com/tcltk/tcl.git
          cd tcl\win
          call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
          nmake -f makefile.vc release OPTS=nomsvcrt INSTALLDIR=%GITHUB_WORKSPACE%\tcldir
          nmake -f makefile.vc install OPTS=nomsvcrt INSTALLDIR=%GITHUB_WORKSPACE%\tcldir

      - name: Build Tk library
        shell: cmd
        run: |
          cd tcltk
          git clone --depth=1 --branch core-8-6-15 https://github.com/tcltk/tk.git
          cd tk\win
          call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
          nmake -f makefile.vc release OPTS=nomsvcrt INSTALLDIR=%GITHUB_WORKSPACE%\tcldir
          nmake -f makefile.vc install OPTS=nomsvcrt INSTALLDIR=%GITHUB_WORKSPACE%\tcldir

      - name: Configure CMake
        run: |
          mkdir build
          cd build
          cmake -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install -DTCL_INCLUDE_PATH=${{ github.workspace }}\tcldir\include ${{ github.workspace }} -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DWITH_MD_LIBRARY=OFF

      - name: Build ScidCommunity
        run: |
          cd build
          cmake --build . --config Release --target INSTALL

      - name: Build Stockfish
        shell: cmd
        run: |
          call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
          git clone --depth=1 --branch sf_17 https://github.com/official-stockfish/Stockfish.git stockfish
          cd stockfish\src
          cl /std:c++20 /DNDEBUG /DUSE_POPCNT /DUSE_AVX2 /DUSE_SSE41 /DUSE_SSSE3 /DUSE_SSE2 /GS- /MT /O2 /Oi /Ot /Oy /GL /EHsc *.cpp nnue/*.cpp nnue/features/*.cpp syzygy/*.cpp /link /LTCG /STACK:reserve=8388608 /OUT:stockfish.exe advapi32.lib
          copy stockfish.exe %GITHUB_WORKSPACE%\install\bin

      - name: Download Stockfish NNUE
        shell: bash
        run: |
          networks=$(grep -Eo "nn-[a-z0-9]+.nnue" stockfish/src/evaluate.h)
          for nnue in $networks; do
            echo "Downloading $nnue"
            curl -o install/bin/$nnue https://data.stockfishchess.org/nn/$nnue
          done

      - name: Package for distribution
        shell: cmd
        run: |
          cd install
          echo === Initial structure ===
          dir
          echo === Deleting useless bin file ===
          del bin
          echo === After deleting bin file, bin directory should now be visible ===
          dir bin
          echo === Creating engines directory ===
          mkdir engines
          echo === Moving chess engines from bin to engines ===
          move bin\stockfish.exe engines\
          move bin\*.nnue engines\
          echo === Copying DLLs to bin ===
          copy %GITHUB_WORKSPACE%\tcldir\bin\tcl86t.dll bin\
          copy %GITHUB_WORKSPACE%\tcldir\bin\tk86t.dll bin\
          copy %GITHUB_WORKSPACE%\tcldir\bin\zlib1.dll bin\
          echo === Copying Tcl/Tk libraries ===
          xcopy /E /I /Y %GITHUB_WORKSPACE%\tcldir\lib\tcl8 lib\tcl8
          xcopy /E /I /Y %GITHUB_WORKSPACE%\tcldir\lib\tcl8.6 lib\tcl8.6
          xcopy /E /I /Y %GITHUB_WORKSPACE%\tcldir\lib\tk8.6 lib\tk8.6
          echo === Copying Snack sound package (64-bit) ===
          mkdir lib\snack
          xcopy /E /I /Y %GITHUB_WORKSPACE%\snack2.2.11\* lib\snack\
          echo === Copying sounds directory ===
          xcopy /E /I /Y %GITHUB_WORKSPACE%\sounds sounds\
          echo === Final structure ===
          dir
          dir bin
          dir engines
          dir lib\snack
          dir sounds

      - name: Upload Windows artifact
        uses: actions/upload-artifact@v7
        with:
          name: scidCommunity-windows-x64
          path: install/

  build-linux-deb:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Get version from tag
        id: get_version
        run: |
          if [[ -n "${{ inputs.version }}" ]]; then
            VERSION="${{ inputs.version }}"
          elif [[ $GITHUB_REF == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
          else
            VERSION="5.1.1"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Export version to env
        run: |
          echo "SCIDCOMMUNITY_VERSION=${{ steps.get_version.outputs.version }}" >> $GITHUB_ENV

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get -y install tcl8.6-dev tk8.6-dev cmake build-essential

      - name: Patch start.tcl to only use Tk 8.6 for DEB package
        run: |
          sed -i 's/if {[[]catch {package require Tk 8.6}[]]} {/if {0 \&\& [catch {package require Tk 8.6}]} {/' tcl/start.tcl

      - name: Configure and build
        run: |
          mkdir build && cd build
          cmake -DCPACK_GENERATOR=DEB \
                -DCPACK_PACKAGE_NAME=scidcommunity \
                -DCPACK_PACKAGE_VERSION=${{ steps.get_version.outputs.version }} \
                -DCPACK_DEBIAN_PACKAGE_MAINTAINER="Hugh Whelan" \
                -DCPACK_DEBIAN_PACKAGE_DEPENDS="tk8.6 (>= 8.6.0), libtcl8.6 (>= 8.6.0), libtk8.6 (>= 8.6.0)" \
                -DCPACK_DEBIAN_PACKAGE_LICENSE=GPL2 \
                -DCMAKE_BUILD_TYPE=Release \
                -DCMAKE_CXX_FLAGS="-fno-exceptions -fno-rtti" \
                -DCMAKE_EXE_LINKER_FLAGS="-static-libstdc++ -static-libgcc" \
                -DCMAKE_INSTALL_PREFIX=/usr \
                ${{ github.workspace }}
          make package

      - name: Upload DEB artifact
        uses: actions/upload-artifact@v7
        with:
          name: scidCommunity-ubuntu-deb
          path: build/*.deb

  build-linux-rpm:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Get version from tag
        id: get_version
        run: |
          if [[ -n "${{ inputs.version }}" ]]; then
            VERSION="${{ inputs.version }}"
          elif [[ $GITHUB_REF == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
          else
            VERSION="5.1.1"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Export version to env
        run: |
          echo "SCIDCOMMUNITY_VERSION=${{ steps.get_version.outputs.version }}" >> $GITHUB_ENV

      - name: Install build dependencies
        run: |
          sudo apt-get update
          sudo apt-get -y install cmake build-essential rpm \
            tcl8.6-dev tk8.6-dev libtcl8.6 libtk8.6

      - name: Configure and build ScidCommunity
        run: |
          mkdir build && cd build
          cmake -DCPACK_GENERATOR=RPM \
                -DCPACK_PACKAGE_NAME=scidcommunity \
                -DCPACK_PACKAGE_VERSION=${{ steps.get_version.outputs.version }} \
                -DCPACK_RPM_PACKAGE_LICENSE=GPL2 \
                -DCMAKE_BUILD_TYPE=Release \
                -DCMAKE_CXX_FLAGS="-fno-exceptions -fno-rtti" \
                -DCMAKE_EXE_LINKER_FLAGS="-static-libstdc++ -static-libgcc" \
                -DCMAKE_INSTALL_PREFIX=/opt/scidcommunity \
                -DCMAKE_INSTALL_RPATH=\$ORIGIN/../lib \
                ${{ github.workspace }}
          make -j$(nproc)
          make install DESTDIR=${{ github.workspace }}/rpm-root

      - name: Bundle Tcl/Tk 8.6 libraries with installation
        run: |
          mkdir -p ${{ github.workspace }}/rpm-root/opt/scidcommunity/lib
          # Copy Tcl/Tk 8.6 shared libraries
          cp -a /usr/lib/x86_64-linux-gnu/libtcl8.6.so* ${{ github.workspace }}/rpm-root/opt/scidcommunity/lib/
          cp -a /usr/lib/x86_64-linux-gnu/libtk8.6.so* ${{ github.workspace }}/rpm-root/opt/scidcommunity/lib/
          # Copy Tcl/Tk script directories (including tcl8 subdirectory with modules)
          cp -rL /usr/share/tcltk/tcl8.6 ${{ github.workspace }}/rpm-root/opt/scidcommunity/lib/
          cp -rL /usr/share/tcltk/tk8.6 ${{ github.workspace }}/rpm-root/opt/scidcommunity/lib/
          # Also copy tcl8 modules directly to lib for module path discovery
          cp -rL /usr/share/tcltk/tcl8.6/tcl8 ${{ github.workspace }}/rpm-root/opt/scidcommunity/lib/

      - name: Create symlink structure and patch Tcl init for module path
        run: |
          # Tcl library has /usr/share/tcltk hardcoded, create symlink structure
          mkdir -p ${{ github.workspace }}/rpm-root/opt/scidcommunity/usr/share/tcltk
          ln -s /opt/scidcommunity/lib/tcl8.6 ${{ github.workspace }}/rpm-root/opt/scidcommunity/usr/share/tcltk/tcl8.6
          ln -s /opt/scidcommunity/lib/tk8.6 ${{ github.workspace }}/rpm-root/opt/scidcommunity/usr/share/tcltk/tk8.6
          
          # Patch init.tcl to add our module path first
          cat >> ${{ github.workspace }}/rpm-root/opt/scidcommunity/lib/tcl8.6/init.tcl << 'EOFTCL'
          # Add bundled module path for scidCommunity
          ::tcl::tm::path add /opt/scidcommunity/usr/share/tcltk/tcl8.6/tcl8
          EOFTCL
          
      - name: Rename binary and create wrapper script
        run: |
          mv ${{ github.workspace }}/rpm-root/opt/scidcommunity/bin/scidCommunity \
             ${{ github.workspace }}/rpm-root/opt/scidcommunity/bin/scidCommunity.bin
          
          cat > ${{ github.workspace }}/rpm-root/opt/scidcommunity/bin/scidCommunity << 'EOF'
          #!/bin/bash
          SCID_DIR="/opt/scidcommunity"
          export LD_LIBRARY_PATH="${SCID_DIR}/lib:${LD_LIBRARY_PATH}"
          # Point Tcl to our bundled location via symlinks
          export TCL_LIBRARY="${SCID_DIR}/usr/share/tcltk/tcl8.6"
          export TK_LIBRARY="${SCID_DIR}/usr/share/tcltk/tk8.6"
          exec "${SCID_DIR}/bin/scidCommunity.bin" "$@"
          EOF
          chmod +x ${{ github.workspace }}/rpm-root/opt/scidcommunity/bin/scidCommunity

      - name: Install desktop file and icons for system menus
        run: |
          # Place desktop entry and icons under /usr/share so desktop environments can find them
          mkdir -p ${{ github.workspace }}/rpm-root/usr/share/applications
          mkdir -p ${{ github.workspace }}/rpm-root/usr/share/icons/hicolor/scalable/apps
          mkdir -p ${{ github.workspace }}/rpm-root/usr/share/icons/hicolor/256x256/apps
          if [ -f ${{ github.workspace }}/data/io.github.whelanh.scidCommunity.desktop ]; then
            cp ${{ github.workspace }}/data/io.github.whelanh.scidCommunity.desktop \
               ${{ github.workspace }}/rpm-root/usr/share/applications/
          fi
          if [ -f ${{ github.workspace }}/data/io.github.whelanh.scidCommunity.svg ]; then
            cp ${{ github.workspace }}/data/io.github.whelanh.scidCommunity.svg \
               ${{ github.workspace }}/rpm-root/usr/share/icons/hicolor/scalable/apps/
          fi
          if [ -f ${{ github.workspace }}/img/scid.png ]; then
            cp ${{ github.workspace }}/img/scid.png \
               ${{ github.workspace }}/rpm-root/usr/share/icons/hicolor/256x256/apps/io.github.whelanh.scidCommunity.png
          fi

      - name: Build RPM package
        run: |
          cd build
          # Use only the prepared rpm-root directory, skip CMake install targets
          cpack -G RPM \
                -D CPACK_PACKAGE_NAME=scidcommunity \
                -D CPACK_PACKAGE_VERSION=${{ steps.get_version.outputs.version }} \
                -D CPACK_RPM_PACKAGE_LICENSE=GPL2 \
                -D CPACK_INSTALL_CMAKE_PROJECTS="" \
                -D CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION="/opt;/opt/scidcommunity;/usr;/usr/local;/usr/local/bin" \
                -D CPACK_INSTALLED_DIRECTORIES="${{ github.workspace }}/rpm-root/opt/scidcommunity;/opt/scidcommunity;${{ github.workspace }}/rpm-root/usr;/usr"

      - name: Upload RPM artifact
        uses: actions/upload-artifact@v7
        with:
          name: scidCommunity-linux-rpm
          path: build/*.rpm

  build-linux-appimage:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Get version from tag
        id: get_version
        run: |
          if [[ -n "${{ inputs.version }}" ]]; then
            VERSION="${{ inputs.version }}"
          elif [[ $GITHUB_REF == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
          else
            VERSION="5.1.1"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Export version to env
        run: |
          echo "SCIDCOMMUNITY_VERSION=${{ steps.get_version.outputs.version }}" >> $GITHUB_ENV

      - name: Install build dependencies
        run: |
          sudo apt-get update
          sudo apt-get -y install cmake build-essential wget \
            tcl8.6-dev tk8.6-dev libtcl8.6 libtk8.6

      - name: Download appimagetool
        run: |
          wget -O appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
          chmod +x appimagetool

      - name: Build ScidCommunity
        run: |
          mkdir build && cd build
          cmake -DCMAKE_BUILD_TYPE=Release \
                -DCMAKE_CXX_FLAGS="-fno-exceptions -fno-rtti" \
                -DCMAKE_EXE_LINKER_FLAGS="-static-libstdc++ -static-libgcc" \
                -DCMAKE_INSTALL_PREFIX=/usr \
                -DCMAKE_INSTALL_RPATH=\$ORIGIN/../lib \
                ${{ github.workspace }}
          make -j$(nproc)
          make install DESTDIR=${{ github.workspace }}/AppDir

      - name: Bundle Tcl/Tk 8.6 libraries
        run: |
          mkdir -p ${{ github.workspace }}/AppDir/usr/lib
          # Copy Tcl/Tk 8.6 shared libraries
          cp -a /usr/lib/x86_64-linux-gnu/libtcl8.6.so* ${{ github.workspace }}/AppDir/usr/lib/
          cp -a /usr/lib/x86_64-linux-gnu/libtk8.6.so* ${{ github.workspace }}/AppDir/usr/lib/
          # Copy Tcl/Tk script directories (including tcl8 subdirectory with modules)
          cp -rL /usr/share/tcltk/tcl8.6 ${{ github.workspace }}/AppDir/usr/lib/
          cp -rL /usr/share/tcltk/tk8.6 ${{ github.workspace }}/AppDir/usr/lib/

      - name: Create AppImage symlink structure and wrapper
        run: |
          # Create symlink structure for Tcl hardcoded paths
          mkdir -p ${{ github.workspace }}/AppDir/usr/share/tcltk
          ln -s ../../lib/tcl8.6 ${{ github.workspace }}/AppDir/usr/share/tcltk/tcl8.6
          ln -s ../../lib/tk8.6 ${{ github.workspace }}/AppDir/usr/share/tcltk/tk8.6
          
          # Patch init.tcl to add AppImage module path
          cat >> ${{ github.workspace }}/AppDir/usr/lib/tcl8.6/init.tcl << 'EOFTCL'
          # Add bundled module path for scidCommunity AppImage
          if {[info exists ::env(APPDIR)]} {
            ::tcl::tm::path add "$::env(APPDIR)/usr/share/tcltk/tcl8.6/tcl8"
          }
          EOFTCL
          
          # Rename binary
          mv ${{ github.workspace }}/AppDir/usr/bin/scidCommunity \
             ${{ github.workspace }}/AppDir/usr/bin/scidCommunity.bin
          
          # Create wrapper script
          cat > ${{ github.workspace }}/AppDir/usr/bin/scidCommunity << 'EOF'
          #!/bin/bash
          APPDIR="${APPDIR:-$(dirname $(dirname $(readlink -f "$0")))}"
          export LD_LIBRARY_PATH="${APPDIR}/usr/lib:${LD_LIBRARY_PATH}"
          # Point Tcl to bundled location via symlinks  
          export TCL_LIBRARY="${APPDIR}/usr/share/tcltk/tcl8.6"
          export TK_LIBRARY="${APPDIR}/usr/share/tcltk/tk8.6"
          exec "${APPDIR}/usr/bin/scidCommunity.bin" "$@"
          EOF
          chmod +x ${{ github.workspace }}/AppDir/usr/bin/scidCommunity
          
          # Create AppRun symlink  
          ln -sf usr/bin/scidCommunity ${{ github.workspace }}/AppDir/AppRun
          
          # Create desktop file (root + standard path for AppImage discovery)
          mkdir -p ${{ github.workspace }}/AppDir/usr/share/applications
          cat > ${{ github.workspace }}/AppDir/io.github.whelanh.scidCommunity.desktop << 'EOF'
          [Desktop Entry]
          Type=Application
          Name=Scid Community
          Comment=Chess database application
          Exec=scidCommunity
          Icon=io.github.whelanh.scidCommunity
          Categories=Game;BoardGame;
          Terminal=false
          EOF
          cp ${{ github.workspace }}/AppDir/io.github.whelanh.scidCommunity.desktop \
             ${{ github.workspace }}/AppDir/usr/share/applications/

          # Install icons (SVG primary, PNG fallback)
          mkdir -p ${{ github.workspace }}/AppDir/usr/share/icons/hicolor/scalable/apps
          mkdir -p ${{ github.workspace }}/AppDir/usr/share/icons/hicolor/256x256/apps
          if [ -f ${{ github.workspace }}/data/io.github.whelanh.scidCommunity.svg ]; then
            cp ${{ github.workspace }}/data/io.github.whelanh.scidCommunity.svg \
               ${{ github.workspace }}/AppDir/usr/share/icons/hicolor/scalable/apps/io.github.whelanh.scidCommunity.svg
          fi
          if [ -f ${{ github.workspace }}/img/scid.png ]; then
            cp ${{ github.workspace }}/img/scid.png \
               ${{ github.workspace }}/AppDir/usr/share/icons/hicolor/256x256/apps/io.github.whelanh.scidCommunity.png
            # AppImage requires the icon file at AppDir root named after Icon= entry
            cp ${{ github.workspace }}/img/scid.png \
              ${{ github.workspace }}/AppDir/io.github.whelanh.scidCommunity.png
          fi

          # Verify desktop file exists for appimagetool
          test -f ${{ github.workspace }}/AppDir/io.github.whelanh.scidCommunity.desktop

      - name: Build AppImage
        run: |
          ARCH=x86_64 ./appimagetool --appimage-extract-and-run \
            ${{ github.workspace }}/AppDir \
            ${{ github.workspace }}/scidCommunity-${{ steps.get_version.outputs.version }}-x86_64.AppImage

      - name: Upload AppImage artifact
        uses: actions/upload-artifact@v7
        with:
          name: scidCommunity-linux-appimage
          path: scidCommunity-*.AppImage

  create-release:
    needs: [build-windows, build-linux-deb, build-linux-rpm, build-linux-appimage, build-macos-app]
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && inputs.create_release)
    permissions:
      contents: write
    steps:
      - name: Set tag name
        id: tag
        run: |
          if [[ -n "${{ inputs.version }}" ]]; then
            echo "tag_name=v${{ inputs.version }}" >> $GITHUB_OUTPUT
          else
            echo "tag_name=${{ github.ref_name }}" >> $GITHUB_OUTPUT
          fi

      - name: Download all artifacts
        uses: actions/download-artifact@v8
        with:
          path: artifacts

      - name: Create Windows ZIP for release
        run: |
          cd artifacts/scidCommunity-windows-x64
          zip -r ../../scidCommunity-windows-x64.zip .
          cd ../..
          mv scidCommunity-windows-x64.zip artifacts/

      - name: Create Release
        uses: softprops/action-gh-release@v3
        with:
          tag_name: ${{ steps.tag.outputs.tag_name }}
          files: |
            artifacts/scidCommunity-windows-x64.zip
            artifacts/scidCommunity-ubuntu-deb/*.deb
            artifacts/scidCommunity-linux-rpm/*.rpm
            artifacts/scidCommunity-linux-appimage/*.AppImage
            artifacts/scidCommunity-macos/*.zip
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
