name: Reusable Package Publish Workflow

on:
  workflow_call:
    inputs:
      package_name:
        description: "Name of the package (e.g. pylume, computer, agent)"
        required: true
        type: string
      package_dir:
        description: "Directory containing the package relative to workspace root (e.g. libs/python/pylume)"
        required: true
        type: string
      version:
        description: "Version to publish"
        required: true
        type: string
      is_lume_package:
        description: "Whether this package includes the lume binary"
        required: false
        type: boolean
        default: false
      base_package_name:
        description: "PyPI package name (e.g. pylume, cua-agent)"
        required: true
        type: string
      make_latest:
        description: "Whether to mark this release as latest (should only be true for lume)"
        required: false
        type: boolean
        default: false
    secrets:
      PYPI_TOKEN:
        required: true
    outputs:
      version:
        description: "The version that was published"
        value: ${{ jobs.build-and-publish.outputs.version }}

jobs:
  build-and-publish:
    runs-on: macos-latest
    permissions:
      contents: write # This permission is needed for creating releases
    outputs:
      version: ${{ steps.set-version.outputs.version }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Full history for release creation

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Create root pdm.lock file
        run: |
          # Create an empty pdm.lock file in the root
          touch pdm.lock

      - name: Install PDM
        uses: pdm-project/setup-pdm@v3
        with:
          python-version: "3.11"
          cache: true

      - name: Set version
        id: set-version
        run: |
          echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV
          echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT

      - name: Initialize PDM in package directory
        run: |
          # Make sure we're working with a properly initialized PDM project
          cd ${{ inputs.package_dir }}

          # Create pdm.lock if it doesn't exist
          if [ ! -f "pdm.lock" ]; then
            echo "No pdm.lock found, initializing PDM project..."
            pdm lock
          fi

      - name: Set version in package
        run: |
          cd ${{ inputs.package_dir }}
          # Replace pdm bump with direct edit of pyproject.toml
          if [[ "$OSTYPE" == "darwin"* ]]; then
            # macOS version of sed needs an empty string for -i
            sed -i '' "s/version = \".*\"/version = \"$VERSION\"/" pyproject.toml
          else
            # Linux version
            sed -i "s/version = \".*\"/version = \"$VERSION\"/" pyproject.toml
          fi
          # Verify version was updated
          echo "Updated version in pyproject.toml:"
          grep "version =" pyproject.toml

      # Conditional step for lume binary download (only for pylume package)
      - name: Download and setup lume binary
        if: inputs.is_lume_package
        run: |
          # Create a temporary directory for extraction
          mkdir -p temp_lume

          # Download the latest lume release directly
          echo "Downloading latest lume version..."
          curl -sL "https://github.com/trycua/lume/releases/latest/download/lume.tar.gz" -o temp_lume/lume.tar.gz

          # Extract the tar file (ignore ownership and suppress warnings)
          cd temp_lume && tar --no-same-owner -xzf lume.tar.gz

          # Make the binary executable
          chmod +x lume

          # Copy the lume binary to the correct location in the pylume package
          mkdir -p "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume"
          cp lume "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume/lume"

          # Verify the binary exists and is executable
          test -x "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume/lume" || { echo "lume binary not found or not executable"; exit 1; }

          # Get the version from the downloaded binary for reference
          LUME_VERSION=$(./lume --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown")
          echo "Using lume version: $LUME_VERSION"

          # Cleanup
          cd "${GITHUB_WORKSPACE}" && rm -rf temp_lume

          # Save the lume version for reference
          echo "LUME_VERSION=${LUME_VERSION}" >> $GITHUB_ENV

      - name: Build and publish
        env:
          PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
        run: |
          cd ${{ inputs.package_dir }}
          # Build with PDM
          pdm build

          # For pylume package, verify the binary is in the wheel
          if [ "${{ inputs.is_lume_package }}" = "true" ]; then
            python -m pip install wheel
            wheel unpack dist/*.whl --dest temp_wheel
            echo "Listing contents of wheel directory:"
            find temp_wheel -type f
            test -f temp_wheel/pylume-*/pylume/lume || { echo "lume binary not found in wheel"; exit 1; }
            rm -rf temp_wheel
            echo "Publishing ${{ inputs.base_package_name }} ${VERSION} with lume ${LUME_VERSION}"
          else
            echo "Publishing ${{ inputs.base_package_name }} ${VERSION}"
          fi

          # Install and use twine directly instead of PDM publish
          echo "Installing twine for direct publishing..."
          pip install twine

          echo "Publishing to PyPI using twine..."
          TWINE_USERNAME="__token__" TWINE_PASSWORD="$PYPI_TOKEN" python -m twine upload dist/*

          # Save the wheel file path for the release
          WHEEL_FILE=$(ls dist/*.whl | head -1)
          echo "WHEEL_FILE=${WHEEL_FILE}" >> $GITHUB_ENV

      - name: Prepare Simple Release Notes
        if: startsWith(github.ref, 'refs/tags/')
        run: |
          # Create release notes based on package type
          echo "# ${{ inputs.base_package_name }} v${VERSION}" > release_notes.md
          echo "" >> release_notes.md

          if [ "${{ inputs.package_name }}" = "pylume" ]; then
            echo "## Python SDK for lume - run macOS and Linux VMs on Apple Silicon" >> release_notes.md
            echo "" >> release_notes.md
            echo "This package provides Python bindings for the lume virtualization tool." >> release_notes.md
            echo "" >> release_notes.md
            echo "## Dependencies" >> release_notes.md
            echo "* lume binary: v${LUME_VERSION}" >> release_notes.md
          elif [ "${{ inputs.package_name }}" = "computer" ]; then
            echo "## Computer control library for the Computer Universal Automation (CUA) project" >> release_notes.md
            echo "" >> release_notes.md
            echo "## Dependencies" >> release_notes.md
            echo "* pylume: ${PYLUME_VERSION:-latest}" >> release_notes.md
          elif [ "${{ inputs.package_name }}" = "agent" ]; then
            echo "## Dependencies" >> release_notes.md
            echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md
            echo "* cua-som: ${SOM_VERSION:-latest}" >> release_notes.md
            echo "" >> release_notes.md
            echo "## Installation Options" >> release_notes.md
            echo "" >> release_notes.md
            echo "### Basic installation with Anthropic" >> release_notes.md
            echo '```bash' >> release_notes.md
            echo "pip install cua-agent[anthropic]==${VERSION}" >> release_notes.md
            echo '```' >> release_notes.md
            echo "" >> release_notes.md
            echo "### With SOM (recommended)" >> release_notes.md
            echo '```bash' >> release_notes.md
            echo "pip install cua-agent[som]==${VERSION}" >> release_notes.md
            echo '```' >> release_notes.md
            echo "" >> release_notes.md
            echo "### All features" >> release_notes.md
            echo '```bash' >> release_notes.md
            echo "pip install cua-agent[all]==${VERSION}" >> release_notes.md
            echo '```' >> release_notes.md
          elif [ "${{ inputs.package_name }}" = "som" ]; then
            echo "## Computer Vision and OCR library for detecting and analyzing UI elements" >> release_notes.md
            echo "" >> release_notes.md
            echo "This package provides enhanced UI understanding capabilities through computer vision and OCR." >> release_notes.md
          elif [ "${{ inputs.package_name }}" = "computer-server" ]; then
            echo "## Computer Server for the Computer Universal Automation (CUA) project" >> release_notes.md
            echo "" >> release_notes.md
            echo "A FastAPI-based server implementation for computer control." >> release_notes.md
            echo "" >> release_notes.md
            echo "## Dependencies" >> release_notes.md
            echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md
            echo "" >> release_notes.md
            echo "## Usage" >> release_notes.md
            echo '```bash' >> release_notes.md
            echo "# Run the server" >> release_notes.md
            echo "cua-computer-server" >> release_notes.md
            echo '```' >> release_notes.md
          elif [ "${{ inputs.package_name }}" = "mcp-server" ]; then
            echo "## MCP Server for the Computer-Use Agent (CUA)" >> release_notes.md
            echo "" >> release_notes.md
            echo "This package provides MCP (Model Context Protocol) integration for CUA agents, allowing them to be used with Claude Desktop, Cursor, and other MCP clients." >> release_notes.md
            echo "" >> release_notes.md
            echo "## Dependencies" >> release_notes.md
            echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md
            echo "* cua-agent: ${AGENT_VERSION:-latest}" >> release_notes.md
            echo "" >> release_notes.md
            echo "## Usage" >> release_notes.md
            echo '```bash' >> release_notes.md
            echo "# Run the MCP server directly" >> release_notes.md
            echo "cua-mcp-server" >> release_notes.md
            echo '```' >> release_notes.md
            echo "" >> release_notes.md
            echo "## Claude Desktop Integration" >> release_notes.md
            echo "Add to your Claude Desktop configuration (~/.config/claude-desktop/claude_desktop_config.json or OS-specific location):" >> release_notes.md
            echo '```json' >> release_notes.md
            echo '"mcpServers": {' >> release_notes.md
            echo '  "cua-agent": {' >> release_notes.md
            echo '    "command": "cua-mcp-server",' >> release_notes.md
            echo '    "args": [],' >> release_notes.md
            echo '    "env": {' >> release_notes.md
            echo '      "CUA_AGENT_LOOP": "OMNI",' >> release_notes.md
            echo '      "CUA_MODEL_PROVIDER": "ANTHROPIC",' >> release_notes.md
            echo '      "CUA_MODEL_NAME": "claude-3-opus-20240229",' >> release_notes.md
            echo '      "ANTHROPIC_API_KEY": "your-api-key",' >> release_notes.md
            echo '      "PYTHONIOENCODING": "utf-8"' >> release_notes.md
            echo '    }' >> release_notes.md
            echo '  }' >> release_notes.md
            echo '}' >> release_notes.md
            echo '```' >> release_notes.md
          fi

          # Add installation section if not agent (which has its own installation section)
          if [ "${{ inputs.package_name }}" != "agent" ]; then
            echo "" >> release_notes.md
            echo "## Installation" >> release_notes.md
            echo '```bash' >> release_notes.md
            echo "pip install ${{ inputs.base_package_name }}==${VERSION}" >> release_notes.md
            echo '```' >> release_notes.md
          fi

          echo "Release notes created:"
          cat release_notes.md

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        if: startsWith(github.ref, 'refs/tags/')
        with:
          name: "${{ inputs.base_package_name }} v${{ env.VERSION }}"
          body_path: release_notes.md
          files: ${{ inputs.package_dir }}/${{ env.WHEEL_FILE }}
          draft: false
          prerelease: false
          make_latest: ${{ inputs.package_name == 'lume' }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
