name: Publish to Cloudsmith

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Release version/tag (e.g., v1.9.123 or 1.9.123, or 'latest' for most recent)"
        required: false
        type: string
        default: "latest"
      dry-run:
        description: "Dry run (don't actually publish)"
        required: false
        type: boolean
        default: true
  workflow_call:
    inputs:
      version:
        description: "Release version/tag"
        required: true
        type: string
      dry-run:
        description: "Dry run (don't actually publish)"
        required: false
        type: boolean
        default: false
    secrets:
      CLOUDSMITH_API_KEY:
        required: true

jobs:
  determine-version:
    runs-on: ubuntu-latest
    outputs:
      tag_name: ${{ steps.resolve.outputs.tag_name }}
      version: ${{ steps.resolve.outputs.version }}
      is_prerelease: ${{ steps.resolve.outputs.is_prerelease }}
    steps:
      - uses: actions/checkout@v6
        with:
          sparse-checkout: |
            .github

      - name: Resolve version and tag
        id: resolve
        run: |
          VERSION_INPUT="${{ inputs.version }}"

          # If version is "latest" or empty, get the latest release
          if [ "$VERSION_INPUT" == "latest" ] || [ -z "$VERSION_INPUT" ]; then
            echo "Fetching latest release..."
            TAG_NAME=$(gh release list --limit 1 --json tagName --jq '.[0].tagName')
            IS_PRERELEASE=$(gh release view "$TAG_NAME" --json isPrerelease --jq '.isPrerelease')
          else
            # Ensure tag has 'v' prefix
            if [[ "$VERSION_INPUT" == v* ]]; then
              TAG_NAME="$VERSION_INPUT"
            else
              TAG_NAME="v$VERSION_INPUT"
            fi

            # Check if release exists and get prerelease status
            if ! gh release view "$TAG_NAME" > /dev/null 2>&1; then
              echo "::error::Release $TAG_NAME not found"
              exit 1
            fi
            IS_PRERELEASE=$(gh release view "$TAG_NAME" --json isPrerelease --jq '.isPrerelease')
          fi

          # Extract version without 'v' prefix
          VERSION="${TAG_NAME#v}"

          echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT

          echo "Resolved to: $TAG_NAME (version: $VERSION, prerelease: $IS_PRERELEASE)"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Check not prerelease
        if: steps.resolve.outputs.is_prerelease == 'true'
        run: |
          echo "::error::Release ${{ steps.resolve.outputs.tag_name }} is a prerelease. Cloudsmith publishing is only for stable releases."
          exit 1

  validate-all-assets:
    runs-on: ubuntu-latest
    needs: [determine-version]
    steps:
      - name: Validate all packages exist in release
        run: |
          TAG_NAME="${{ needs.determine-version.outputs.tag_name }}"
          VERSION="${{ needs.determine-version.outputs.version }}"

          echo "Validating packages for release $TAG_NAME..."

          # Get list of assets from release (API call, no download)
          ASSETS=$(gh release view "$TAG_NAME" --json assets --jq '.assets[].name')

          MISSING=0
          REQUIRED_FILES=(
            "quarto-${VERSION}-linux-amd64.deb"
            "quarto-${VERSION}-linux-arm64.deb"
            "quarto-${VERSION}-linux-x86_64.rpm"
            "quarto-${VERSION}-linux-aarch64.rpm"
          )

          for FILE in "${REQUIRED_FILES[@]}"; do
            if echo "$ASSETS" | grep -q "^${FILE}$"; then
              echo "✓ Found: $FILE"
            else
              echo "::error::Missing: $FILE"
              MISSING=$((MISSING + 1))
            fi
          done

          if [ $MISSING -gt 0 ]; then
            echo "::error::$MISSING package(s) missing from release. All 4 packages required for Cloudsmith publishing."
            exit 1
          fi

          echo "All required packages present in release"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_REPO: quarto-dev/quarto-cli

  publish-cloudsmith:
    runs-on: ubuntu-latest
    needs: [determine-version, validate-all-assets]
    strategy:
      matrix:
        arch: [x86_64, aarch64]
        format: [deb, rpm]
    steps:
      - name: Set package architecture name
        id: pkg_arch
        run: |
          if [ "${{ matrix.format }}" == "deb" ]; then
            if [ "${{ matrix.arch }}" == "x86_64" ]; then
              echo "arch_name=amd64" >> $GITHUB_OUTPUT
            else
              echo "arch_name=arm64" >> $GITHUB_OUTPUT
            fi
          else
            if [ "${{ matrix.arch }}" == "x86_64" ]; then
              echo "arch_name=x86_64" >> $GITHUB_OUTPUT
            else
              echo "arch_name=aarch64" >> $GITHUB_OUTPUT
            fi
          fi

      - name: Download and validate package from release
        run: |
          TAG_NAME="${{ needs.determine-version.outputs.tag_name }}"
          VERSION="${{ needs.determine-version.outputs.version }}"
          ARCH_NAME="${{ steps.pkg_arch.outputs.arch_name }}"
          FILE_NAME="quarto-${VERSION}-linux-${ARCH_NAME}.${{ matrix.format }}"

          echo "Downloading $FILE_NAME from release $TAG_NAME..."

          if ! gh release download "$TAG_NAME" --pattern "$FILE_NAME"; then
            echo "::error::Failed to download $FILE_NAME from release $TAG_NAME"
            exit 1
          fi

          if [ ! -f "$FILE_NAME" ]; then
            echo "::error::Package file $FILE_NAME not found in release"
            exit 1
          fi

          echo "✓ Successfully downloaded and validated: $FILE_NAME"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_REPO: quarto-dev/quarto-cli

      - name: Install and authenticate Cloudsmith CLI
        uses: cloudsmith-io/cloudsmith-cli-action@v2.0.2
        with:
          api-key: ${{ secrets.CLOUDSMITH_API_KEY }}

      - name: Push ${{ matrix.format }} ${{ matrix.arch }} to Cloudsmith${{ inputs.dry-run && ' (DRY RUN)' || '' }}
        run: |
          cloudsmith push ${{ matrix.format }} \
            posit/open/any-distro/any-version \
            "quarto-${{ needs.determine-version.outputs.version }}-linux-${{ steps.pkg_arch.outputs.arch_name }}.${{ matrix.format }}" \
            --republish \
            ${{ inputs.dry-run && '--dry-run' || '' }}
