name: Build All Packages

on:
  push:
    tags:
      - '*'
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to build (leave empty for auto)'
        required: false
        type: string

jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.version.outputs.version }}
      is_release: ${{ steps.version.outputs.is_release }}
    steps:
      - uses: actions/checkout@v4
      - name: Determine version
        id: version
        run: |
          if [[ "${GIT_REF}" =~ ^refs/tags/ ]]; then
            G4F_VERSION="${REF_NAME}"
            IS_RELEASE="true"
          elif [[ -n "${{ inputs.version }}" ]]; then
            G4F_VERSION="${{ inputs.version }}"
            IS_RELEASE="false"
          else
            G4F_VERSION="0.0.0-dev"
            IS_RELEASE="false"
          fi
          echo "version=${G4F_VERSION}" >> $GITHUB_OUTPUT
          echo "is_release=${IS_RELEASE}" >> $GITHUB_OUTPUT
          echo "Building version: ${G4F_VERSION}"

        env:
          GIT_REF: ${{ github.ref }}
          REF_NAME: ${{ github.ref_name }}
  # PyPI Package
  build-pypi:
    runs-on: ubuntu-latest
    needs: prepare
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"
      - name: Install build tools
        run: |
          python -m pip install --upgrade pip
          python -m pip install build twine
      - name: Build package
        env:
          G4F_VERSION: ${{ needs.prepare.outputs.version }}
        run: python -m build
      - name: Verify package
        run: |
          python -m twine check dist/*
          ls -la dist/
      - name: Upload PyPI package artifact (combined)
        uses: actions/upload-artifact@v4
        with:
          name: pypi-package
          path: dist/
      - name: Upload PyPI build artifacts (individual)
        run: |
          for f in dist/*; do
            echo "Uploading $f"
          done
        shell: bash
      - name: Upload wheel artifact
        uses: actions/upload-artifact@v4
        with:
          name: pypi-wheel
          path: dist/*.whl
      - name: Upload sdist artifact
        uses: actions/upload-artifact@v4
        with:
          name: pypi-sdist
          path: dist/*.tar.gz

  # Executables (built with g4f-go, no Nuitka)
  # Cross-compiles the Go launcher on ubuntu-latest for every OS/arch.
  # The embedded CPython runtime zips are generated by fetch-python.sh
  # (linux) / fetched & merged per-platform (windows, darwin, freebsd).
  build-g4f-go:
    runs-on: ubuntu-latest
    needs: prepare
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: "1.22"
          cache-dependency-path: g4f-go/go.mod
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Install tooling
        run: |
          python -m pip install --upgrade pip
          pip install requests aiohttp brotli pycryptodome nest-asyncio2
          sudo apt-get update
          sudo apt-get install -y rsync zip
      - name: Fetch & merge Python runtimes (all platforms)
        working-directory: g4f-go
        env:
          G4F_VERSION: ${{ needs.prepare.outputs.version }}
        run: ./fetch-python.sh
      - name: Cross-compile g4f-go launchers (all platforms)
        working-directory: g4f-go
        env:
          G4F_VERSION: ${{ needs.prepare.outputs.version }}
        run: ./build-all.sh
      - name: Upload g4f-go executables (combined)
        uses: actions/upload-artifact@v4
        with:
          name: g4f-go
          path: g4f-go/dist/*
      - name: Upload g4f-go executables (individual per platform)
        run: |
          for zip in g4f-go/dist/*.zip; do
            base="$(basename "$zip" .zip)"
            echo "Uploading $zip as artifact g4f-go-${base}"
          done
        shell: bash
      - name: Upload g4f-go windows-amd64
        uses: actions/upload-artifact@v4
        with:
          name: g4f-go-windows-amd64
          path: g4f-go/dist/g4f-go-*-windows-amd64.zip
          if-no-files-found: error
      - name: Upload g4f-go linux-amd64
        uses: actions/upload-artifact@v4
        with:
          name: g4f-go-linux-amd64
          path: g4f-go/dist/g4f-go-*-linux-amd64.zip
          if-no-files-found: error
      - name: Upload g4f-go linux-arm64
        uses: actions/upload-artifact@v4
        with:
          name: g4f-go-linux-arm64
          path: g4f-go/dist/g4f-go-*-linux-arm64.zip
          if-no-files-found: error
      - name: Upload g4f-go darwin-arm64
        uses: actions/upload-artifact@v4
        with:
          name: g4f-go-darwin-arm64
          path: g4f-go/dist/g4f-go-*-darwin-arm64.zip
          if-no-files-found: error
      - name: Upload g4f-go darwin-amd64
        uses: actions/upload-artifact@v4
        with:
          name: g4f-go-darwin-amd64
          path: g4f-go/dist/g4f-go-*-darwin-amd64.zip
          if-no-files-found: error

  # Docker Images
  build-docker:
    runs-on: ubuntu-latest
    needs: prepare
    if: needs.prepare.outputs.is_release == 'true'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Set up QEMU
        uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
      - name: Get metadata for Docker
        id: metadata
        uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
        with:
          images: |
            hlohaus789/g4f
      - name: Log in to Docker Hub
        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Build and push armv7 image
        uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
        with:
            context: .
            file: docker/Dockerfile-armv7
            platforms: linux/arm/v7
            push: true
            provenance: mode=max
            sbom: true
            tags: |
              hlohaus789/g4f:latest-armv7
              hlohaus789/g4f:${{ needs.prepare.outputs.version }}-armv7
            labels: ${{ steps.metadata.outputs.labels }}
            build-args: |
              G4F_VERSION=${{ needs.prepare.outputs.version }}
      - name: Build and push slim images
        uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
        with:
          context: .
          file: docker/Dockerfile-slim
          platforms: linux/amd64,linux/arm64
          push: true
          provenance: mode=max
          sbom: true
          tags: |
            hlohaus789/g4f:latest-slim
            hlohaus789/g4f:${{ needs.prepare.outputs.version }}-slim
          labels: ${{ steps.metadata.outputs.labels }}
          build-args: |
            G4F_VERSION=${{ needs.prepare.outputs.version }}
      - name: Build and push image
        uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
        with:
          context: .
          file: docker/Dockerfile
          platforms: linux/amd64
          push: true
          provenance: mode=max
          sbom: true
          tags: ${{ steps.metadata.outputs.tags }}
          labels: ${{ steps.metadata.outputs.labels }}
          build-args: |
            G4F_VERSION=${{ needs.prepare.outputs.version }}

  # Release Creation
  create-release:
    runs-on: ubuntu-latest
    needs: [prepare, build-pypi, build-g4f-go]
    if: needs.prepare.outputs.is_release == 'true'
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - name: Download PyPI artifacts
        uses: actions/download-artifact@v4
        with:
          name: pypi-package
          path: ./release/pypi
      - name: Download g4f-go artifacts
        uses: actions/download-artifact@v4
        with:
          name: g4f-go
          path: ./release/g4f-go
      - name: Download individual g4f-go platform artifacts
        uses: actions/download-artifact@v4
        with:
          path: ./release/g4f-go/individual
          pattern: g4f-go-*
          merge-multiple: true
      - name: Flatten all release assets
        run: |
          mkdir -p ./release/flat
          find ./release -type f | sort
          cp -v ./release/pypi/* ./release/flat/ 2>/dev/null || true
          cp -v ./release/g4f-go/dist/*.zip ./release/flat/ 2>/dev/null || true
          cp -v ./release/g4f-go/individual/* ./release/flat/ 2>/dev/null || true
          echo "--- Final release assets ---"
          find ./release/flat -type f | sort
      - name: Create Release with Assets
        uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
        with:
          tag_name: ${{ needs.prepare.outputs.version }}
          name: Release ${{ needs.prepare.outputs.version }}
          append_body: true
          body: |
            ### Download Options

            **Python Package:**
            - PyPI: `pip install g4f==${{ needs.prepare.outputs.version }}`

            **Executables (g4f-go, self-contained with embedded Python):**
            - Windows amd64: `g4f-go-${{ needs.prepare.outputs.version }}-windows-amd64.zip`
            - Linux x64: `g4f-go-${{ needs.prepare.outputs.version }}-linux-amd64.zip`
            - Linux ARM64: `g4f-go-${{ needs.prepare.outputs.version }}-linux-arm64.zip`
            - macOS x64: `g4f-go-${{ needs.prepare.outputs.version }}-darwin-amd64.zip`
            - macOS ARM64: `g4f-go-${{ needs.prepare.outputs.version }}-darwin-arm64.zip`
            - FreeBSD amd64: `g4f-go-${{ needs.prepare.outputs.version }}-freebsd-amd64.zip`

            **System Packages:**
            - WinGet: `winget install gpt4free`

            **Docker:**
            - `docker pull hlohaus789/g4f:${{ needs.prepare.outputs.version }}`
            - `docker pull hlohaus789/g4f:${{ needs.prepare.outputs.version }}-slim`

            💻 **Having trouble with the .exe from this release?**
            👉 Check out the Windows launcher for GPT4Free instead:
            🔗 [https://github.com/gpt4free/g4f.exe](https://github.com/gpt4free/g4f.exe) 🚀
          draft: false
          prerelease: false
          files: ./release/flat/*
          token: ${{ secrets.GITHUB_TOKEN }}

  # Publish to PyPI (only for releases)
  # publish-pypi:
  #   runs-on: ubuntu-latest
  #   needs: [prepare, build-pypi, create-release]
  #   if: needs.prepare.outputs.is_release == 'true'
  #   environment:
  #     name: pypi
  #     url: https://pypi.org/p/g4f
  #   permissions:
  #     id-token: write
  #   steps:
  #     - name: Download PyPI artifacts
  #       uses: actions/download-artifact@v4
  #       with:
  #         name: pypi-package
  #         path: dist/
  #     - name: Publish to PyPI
  #       uses: pypa/gh-action-pypi-publish@release/v1
