name: Release

on:
  push:
    tags:
      - "v*.*.*"

permissions:
  contents: write

jobs:
  build:
    name: ${{ matrix.name }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: Linux x86_64 (tar.gz)
            target: x86_64-unknown-linux-gnu
            format: tar-gz
          - name: Linux x86_64 (deb)
            target: x86_64-unknown-linux-gnu
            format: deb
            deps: rpm
          - name: Linux x86_64 (rpm)
            target: x86_64-unknown-linux-gnu
            format: rpm
            deps: rpm
          - name: Arch Linux x86_64
            target: x86_64-unknown-linux-gnu
            format: arch
          - name: Linux x86_64 (musl)
            target: x86_64-unknown-linux-musl
            format: musl-tar-gz
            deps: musl-tools
          - name: Linux ARM64 (tar.gz)
            target: aarch64-unknown-linux-gnu
            format: tar-gz
            deps: gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
          - name: Linux ARM64 (deb)
            target: aarch64-unknown-linux-gnu
            format: deb
            deps: gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu rpm
          - name: Linux ARM64 (rpm)
            target: aarch64-unknown-linux-gnu
            format: rpm
            deps: gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu rpm
          - name: Arch Linux ARM64
            target: aarch64-unknown-linux-gnu
            format: arch-arm64
            deps: gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
          - name: Linux ARM64 (musl)
            target: aarch64-unknown-linux-musl
            format: musl-tar-gz
            deps: musl-tools gcc-aarch64-linux-gnu
          - name: Windows x86_64 (zip)
            target: x86_64-pc-windows-gnu
            format: zip
            deps: gcc-mingw-w64-x86-64

    runs-on: ubuntu-latest
    env:
      CARGO_TERM_COLOR: always
    steps:
      - uses: actions/checkout@v7

      - name: Extract tag name
        run: echo "VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV

      - uses: dtolnay/rust-toolchain@stable

      - name: Install target
        run: rustup target add ${{ matrix.target }}

      - uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

      - name: Install system dependencies
        if: matrix.deps != ''
        run: |
          sudo apt-get update -qq
          sudo apt-get install -y -qq ${{ matrix.deps }}

      - name: Install packaging tools
        if: matrix.format == 'deb' || matrix.format == 'rpm'
        run: |
          cargo install cargo-deb --locked
          cargo install cargo-rpm --locked

      - name: Build and package
        shell: bash
        run: |
          set -euxo pipefail
          mkdir -p dist

          case "${{ matrix.format }}" in
            tar-gz)
              cargo build --release --target ${{ matrix.target }}
              cp target/${{ matrix.target }}/release/leenfetch dist/leenfetch
              tar -czf "dist/leenfetch-${VERSION}-linux-${{ matrix.target == 'x86_64-unknown-linux-gnu' && 'x86_64' || 'aarch64' }}.tar.gz" -C dist leenfetch
              rm dist/leenfetch
              ;;

            deb)
              cargo build --release --target ${{ matrix.target }}
              cargo deb ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '--no-strip ' || '' }}--target ${{ matrix.target }}
              cp target/${{ matrix.target }}/debian/*.deb "dist/leenfetch-${VERSION}-debian-${{ matrix.target == 'x86_64-unknown-linux-gnu' && 'x86_64' || 'aarch64' }}.deb"
              ;;

            rpm)
              cargo build --release --target ${{ matrix.target }}
              case "${{ matrix.target }}" in
                x86_64-unknown-linux-gnu)
                  cargo rpm init 2>/dev/null || true
                  cargo rpm build 2>/dev/null || true
                  find target/release/rpmbuild -name "*.rpm" -exec cp {} "dist/leenfetch-${VERSION}-rhel-x86_64.rpm" \; 2>/dev/null || true
                  ;;
                aarch64-unknown-linux-gnu)
                  {
                    echo "Name: leenfetch"
                    echo "Version: ${VERSION#v}"
                    echo "Release: 1%{?dist}"
                    echo "Summary: Fast, minimal system info tool"
                    echo "License: MIT"
                    echo "BuildArch: aarch64"
                    echo ""
                    echo "%description"
                    echo "Fast and customizable system info tool for the terminal."
                    echo ""
                    echo "%install"
                    echo "install -Dm0755 %{_sourcedir}/leenfetch %{buildroot}%{_bindir}/leenfetch"
                    echo ""
                    echo "%files"
                    echo "%{_bindir}/leenfetch"
                  } > dist/leenfetch.spec
                  cp target/${{ matrix.target }}/release/leenfetch dist/leenfetch
                  rpmbuild -bb dist/leenfetch.spec \
                    --define "_sourcedir $PWD/dist" \
                    --define "_rpmdir $PWD/dist" \
                    --define "_target_cpu aarch64" \
                    --nodeps 2>/dev/null || true
                  for f in $(find dist -name "*.rpm" -type f 2>/dev/null); do
                    mv "$f" "dist/leenfetch-${VERSION}-rhel-aarch64.rpm" 2>/dev/null || true
                  done
                  rm -f dist/leenfetch dist/leenfetch.spec
                  ;;
              esac
              ;;

            arch)
              cargo build --release --target ${{ matrix.target }}
              docker run --rm -v $PWD:/work archlinux:latest bash -c "
                pacman -Sy --noconfirm base-devel
                cp /work/target/${{ matrix.target }}/release/leenfetch /work/
                cd /work
                useradd build
                chown build:build leenfetch PKGBUILD
                su build -c 'makepkg -f' || true
                cp *.pkg.tar.zst /work/dist/ 2>/dev/null || true
              " || true
              if [ -f dist/*.pkg.tar.zst ]; then
                mv dist/*.pkg.tar.zst "dist/leenfetch-${VERSION}-arch-x86_64.pkg.tar.zst"
              else
                BIN=target/${{ matrix.target }}/release/leenfetch
                mkdir -p pkg/usr/bin
                cp "$BIN" pkg/usr/bin/leenfetch
                printf 'pkgname = leenfetch\npkgver = %s\npkgdesc = Fast, minimal system info tool\nurl = https://github.com/drunkleen/leenfetch\nbuilddate = %d\npackager = DrunkLeen\nsize = %d\narch = x86_64\nlicense = MIT\n' \
                  "${VERSION#v}" "$(date +%s)" "$(stat -c%s "$BIN")" > .PKGINFO
                tar -c --zstd -f "dist/leenfetch-${VERSION}-arch-x86_64.pkg.tar.zst" .PKGINFO -C pkg . 2>/dev/null || true
                rm -rf pkg .PKGINFO
              fi
              ;;

            arch-arm64)
              cargo build --release --target ${{ matrix.target }}
              BIN=target/${{ matrix.target }}/release/leenfetch
              mkdir -p pkg/usr/bin
              cp "$BIN" pkg/usr/bin/leenfetch
              printf 'pkgname = leenfetch\npkgver = %s\npkgdesc = Fast, minimal system info tool\nurl = https://github.com/drunkleen/leenfetch\nbuilddate = %d\npackager = DrunkLeen\nsize = %d\narch = aarch64\nlicense = MIT\n' \
                "${VERSION#v}" "$(date +%s)" "$(stat -c%s "$BIN")" > .PKGINFO
              tar -c --zstd -f "dist/leenfetch-${VERSION}-arch-aarch64.pkg.tar.zst" .PKGINFO -C pkg . 2>/dev/null || true
              rm -rf pkg .PKGINFO
              ;;

            musl-tar-gz)
              CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-gnu-gcc \
                cargo build --release --target ${{ matrix.target }}
              cp target/${{ matrix.target }}/release/leenfetch dist/leenfetch
              tar -czf "dist/leenfetch-${VERSION}-linux-${{ matrix.target == 'x86_64-unknown-linux-musl' && 'x86_64' || 'aarch64' }}-musl.tar.gz" -C dist leenfetch
              rm dist/leenfetch
              ;;

            zip)
              cargo build --release --target ${{ matrix.target }}
              cp target/${{ matrix.target }}/release/leenfetch.exe dist/leenfetch.exe
              zip -j "dist/leenfetch-${VERSION}-windows-x86_64.zip" dist/leenfetch.exe
              rm dist/leenfetch.exe
              ;;
          esac

      - uses: actions/upload-artifact@v7
        with:
          name: ${{ matrix.name }}
          path: dist/*

  aur-publish:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7

      - name: Extract version
        run: echo "VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV

      - name: Compute source checksum
        run: |
          curl -sL "https://github.com/${{ github.repository }}/archive/refs/tags/${VERSION}.tar.gz" -o source.tar.gz
          echo "SHA256=$(sha256sum source.tar.gz | cut -d' ' -f1)" >> $GITHUB_ENV

      - name: Set up SSH key for AUR
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.AUR_SECRET }}" > ~/.ssh/aur
          chmod 600 ~/.ssh/aur
          ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts 2>/dev/null
          cat >> ~/.ssh/config << 'EOF'
          Host aur.archlinux.org
            IdentityFile ~/.ssh/aur
            User aur
          EOF

      - name: Update AUR PKGBUILD and push
        run: |
          git clone ssh://aur@aur.archlinux.org/leenfetch.git aur-repo
          cd aur-repo
          git config user.name "DrunkLeen"
          git config user.email "snape@drunkleen.com"

          sed -i "s/^pkgver=.*/pkgver=${VERSION#v}/" PKGBUILD
          sed -i "s/^sha256sums=.*/sha256sums=('${SHA256}')/" PKGBUILD

          docker run --rm -v $PWD:/work archlinux:latest bash -c "
            pacman -Sy --noconfirm base-devel
            cd /work
            useradd build
            chown build:build /work PKGBUILD
            su build -c 'makepkg --printsrcinfo' > .SRCINFO.tmp
            [ -s .SRCINFO.tmp ] || { echo '.SRCINFO is empty - makepkg failed'; exit 1; }
            mv .SRCINFO.tmp .SRCINFO
          "

          git add PKGBUILD .SRCINFO
          git commit -m "Update to ${VERSION}"
          git push origin master

  release:
    needs: aur-publish
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7

      - name: Extract tag name
        run: echo "VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV

      - uses: actions/download-artifact@v8
        with:
          path: dist

      - name: Flatten downloaded artifacts
        run: |
          find dist -mindepth 2 -type f -exec mv -f {} dist/ \;
          find dist -mindepth 1 -type d -empty -delete

      - name: Generate checksums
        run: |
          cd dist
          find . -type f ! -name "SHA256SUMS.txt" -print0 | xargs -0 sha256sum > SHA256SUMS.txt

      - name: Build release notes body
        env:
          REPO: ${{ github.repository }}
        run: |
          set -euxo pipefail

          VERSION_NUM=${VERSION#v}
          sed -n "/^## \[${VERSION_NUM}\]/,/^## \[/p" CHANGELOG.md | head -n -2 > dist/CHANGELOG_SECTION.md

          {
            echo "# 🐧 LeenFetch ${VERSION}"
            echo ""
            echo "## Changelog"
            echo ""
            cat dist/CHANGELOG_SECTION.md
            echo ""
            echo "---"
            echo ""
            echo "## 📦 Available Downloads"
            echo ""
            echo "| File | Platform | Arch |"
            echo "|------|----------|------|"
            echo "| [leenfetch-${VERSION}-arch-x86_64.pkg.tar.zst](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-arch-x86_64.pkg.tar.zst) | Arch Linux | x86_64 |"
            echo "| [leenfetch-${VERSION}-arch-aarch64.pkg.tar.zst](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-arch-aarch64.pkg.tar.zst) | Arch Linux | ARM64 |"
            echo "| [leenfetch-${VERSION}-debian-x86_64.deb](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-debian-x86_64.deb) | Debian/Ubuntu | x86_64 |"
            echo "| [leenfetch-${VERSION}-debian-aarch64.deb](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-debian-aarch64.deb) | Debian/Ubuntu | ARM64 |"
            echo "| [leenfetch-${VERSION}-rhel-x86_64.rpm](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-rhel-x86_64.rpm) | RHEL/Fedora | x86_64 |"
            if [ -f "dist/leenfetch-${VERSION}-rhel-aarch64.rpm" ]; then
              echo "| [leenfetch-${VERSION}-rhel-aarch64.rpm](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-rhel-aarch64.rpm) | RHEL/Fedora | ARM64 |"
            fi
            echo "| [leenfetch-${VERSION}-linux-x86_64.tar.gz](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-linux-x86_64.tar.gz) | Linux (tar.gz) | x86_64 |"
            echo "| [leenfetch-${VERSION}-linux-aarch64.tar.gz](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-linux-aarch64.tar.gz) | Linux (tar.gz) | ARM64 |"
            echo "| [leenfetch-${VERSION}-linux-x86_64-musl.tar.gz](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-linux-x86_64-musl.tar.gz) | Linux (musl, static) | x86_64 |"
            if [ -f "dist/leenfetch-${VERSION}-linux-aarch64-musl.tar.gz" ]; then
              echo "| [leenfetch-${VERSION}-linux-aarch64-musl.tar.gz](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-linux-aarch64-musl.tar.gz) | Linux (musl, static) | ARM64 |"
            fi
            echo "| [leenfetch-${VERSION}-windows-x86_64.zip](https://github.com/drunkleen/leenfetch/releases/download/${VERSION}/leenfetch-${VERSION}-windows-x86_64.zip) | Windows | x86_64 |"
            echo ""
            echo "## Checksums"
            echo '```'
          } > dist/RELEASE.md
          cat dist/SHA256SUMS.txt >> dist/RELEASE.md
          echo '```' >> dist/RELEASE.md
          rm -f dist/CHANGELOG_SECTION.md

      - name: Append generated release notes
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          REPO: ${{ github.repository }}
        run: |
          set -euxo pipefail
          if gh api -X POST repos/$REPO/releases/generate-notes -f tag_name=${VERSION} --jq '.body' > /tmp/notes.md 2>/dev/null; then
            {
              cat dist/RELEASE.md
              echo
              echo "## Changes & Commits"
              echo
              cat /tmp/notes.md
            } > dist/RELEASE_NOTES.md
            mv dist/RELEASE_NOTES.md dist/RELEASE.md
          fi

      - name: Upload Release Assets
        uses: softprops/action-gh-release@v2
        with:
          files: dist/*
          generate_release_notes: false
          body_path: dist/RELEASE.md
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
