name: 'Setup Virtual Environment'
description: 'Create a Python virtual environment in the checkout folder for clean isolation'

inputs:
  venv-name:
    description: 'Name for the virtual environment directory (will be created in workspace)'
    required: false
    default: '.venv'
  python-version:
    description: 'Python version to use (passed to setup-python action on self-hosted)'
    required: false
    default: '3.10'
  requirements-file:
    description: 'Optional requirements file to install'
    required: false
    default: ''
  install-package:
    description: 'Optional package specification to install (e.g., ".[dev]" or "package-name")'
    required: false
    default: ''
  extra-index-url:
    description: 'Optional extra index URL for pip'
    required: false
    default: ''

outputs:
  venv-path:
    description: 'Full path to the venv directory'
    value: ${{ steps.create-venv-windows.outputs.venv-path || steps.create-venv-linux.outputs.venv-path }}
  python-path:
    description: 'Path to the Python executable in the venv'
    value: ${{ steps.create-venv-windows.outputs.python-path || steps.create-venv-linux.outputs.python-path }}

runs:
  using: "composite"
  steps:
    # For GitHub-hosted runners, use actions/setup-python
    - name: Setup Python (GitHub-hosted)
      if: ${{ !contains(runner.name, 'stx') && !contains(runner.name, 'rai') && !contains(runner.name, 'selfhost') }}
      uses: actions/setup-python@v6
      with:
        python-version: ${{ inputs.python-version }}

    # For self-hosted runners, use our custom setup
    - name: Setup Python (self-hosted)
      id: setup-python-selfhosted
      if: ${{ contains(runner.name, 'stx') || contains(runner.name, 'rai') || contains(runner.name, 'selfhost') }}
      uses: ./.github/actions/setup-python
      with:
        python-version: ${{ inputs.python-version }}

    # Set the Python path for use in subsequent steps
    - name: Set Python path (self-hosted Windows)
      if: ${{ (contains(runner.name, 'stx') || contains(runner.name, 'rai') || contains(runner.name, 'selfhost')) && runner.os == 'Windows' }}
      shell: powershell
      run: |
        $PYTHON_DIR = "$env:GITHUB_WORKSPACE\.python-${{ inputs.python-version }}"
        $PYTHON_EXE = "$PYTHON_DIR\python.exe"
        Write-Host "Using Python at: $PYTHON_EXE"
        "SETUP_PYTHON_PATH=$PYTHON_EXE" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append

    - name: Set Python path (self-hosted Linux/macOS)
      if: ${{ (contains(runner.name, 'stx') || contains(runner.name, 'rai') || contains(runner.name, 'selfhost')) && runner.os != 'Windows' }}
      shell: bash
      run: |
        # Use the python that setup-python found/installed
        PYTHON_EXE="${{ steps.setup-python-selfhosted.outputs.python-path }}"
        echo "Using Python at: $PYTHON_EXE"
        echo "SETUP_PYTHON_PATH=$PYTHON_EXE" >> $GITHUB_ENV

    # Set Python path for GitHub-hosted runners (Windows)
    - name: Set Python path (GitHub-hosted Windows)
      if: ${{ !contains(runner.name, 'stx') && !contains(runner.name, 'rai') && !contains(runner.name, 'selfhost') && runner.os == 'Windows' }}
      shell: powershell
      run: |
        # On GitHub-hosted runners, actions/setup-python puts python in PATH
        $PYTHON_EXE = (Get-Command python).Source
        Write-Host "Using Python at: $PYTHON_EXE"
        "SETUP_PYTHON_PATH=$PYTHON_EXE" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append

    # Set Python path for GitHub-hosted runners (Linux/macOS)
    - name: Set Python path (GitHub-hosted Linux/macOS)
      if: ${{ !contains(runner.name, 'stx') && !contains(runner.name, 'rai') && !contains(runner.name, 'selfhost') && runner.os != 'Windows' }}
      shell: bash
      run: |
        # On GitHub-hosted runners, actions/setup-python puts python in PATH
        PYTHON_EXE=$(which python3 || which python)
        echo "Using Python at: $PYTHON_EXE"
        echo "SETUP_PYTHON_PATH=$PYTHON_EXE" >> $GITHUB_ENV

    - name: Create virtual environment (Windows)
      id: create-venv-windows
      if: runner.os == 'Windows'
      shell: powershell
      run: |
        $ErrorActionPreference = "Stop"
        $VENV_NAME = "${{ inputs.venv-name }}"
        $VENV_PATH = "$env:GITHUB_WORKSPACE\$VENV_NAME"
        $BASE_PYTHON = $env:SETUP_PYTHON_PATH

        Write-Host "Creating virtual environment at $VENV_PATH..."
        Write-Host "Using base Python: $BASE_PYTHON"

        # Verify we're using the correct Python
        & $BASE_PYTHON --version

        # Remove existing venv if present
        if (Test-Path $VENV_PATH) {
          Write-Host "Removing existing venv..."
          Remove-Item -Recurse -Force $VENV_PATH
        }

        # Create the venv using the explicit Python path
        & $BASE_PYTHON -m venv $VENV_PATH
        if ($LASTEXITCODE -ne 0) {
          Write-Host "venv creation failed, trying with --without-pip..."
          & $BASE_PYTHON -m venv $VENV_PATH --without-pip
          if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

          # Install pip manually
          Write-Host "Installing pip manually..."
          Invoke-WebRequest -Uri "https://bootstrap.pypa.io/get-pip.py" -OutFile "$VENV_PATH\get-pip.py" -UseBasicParsing
          & "$VENV_PATH\Scripts\python.exe" "$VENV_PATH\get-pip.py"
        }

        $PYTHON_PATH = "$VENV_PATH\Scripts\python.exe"
        $PIP_PATH = "$VENV_PATH\Scripts\pip.exe"

        # PREPEND venv Scripts to PATH (write to file first, then prepend)
        # This ensures venv Python takes precedence over system Python
        "$VENV_PATH\Scripts" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append

        # Upgrade pip
        & $PYTHON_PATH -m pip install --upgrade pip

        "venv-path=$VENV_PATH" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
        "python-path=$PYTHON_PATH" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append

        Write-Host "Virtual environment created successfully!"
        Write-Host "Venv Python location:"
        & $PYTHON_PATH -c "import sys; print(sys.executable)"
        & $PYTHON_PATH --version

    - name: Create virtual environment (Linux/macOS)
      id: create-venv-linux
      if: runner.os != 'Windows'
      shell: bash
      run: |
        VENV_NAME="${{ inputs.venv-name }}"
        VENV_PATH="$GITHUB_WORKSPACE/$VENV_NAME"
        BASE_PYTHON="$SETUP_PYTHON_PATH"

        echo "Creating virtual environment at $VENV_PATH..."
        echo "Using base Python: $BASE_PYTHON"

        # Verify we're using the correct Python
        "$BASE_PYTHON" --version

        # Remove existing venv if present
        if [ -d "$VENV_PATH" ]; then
          echo "Removing existing venv..."
          rm -rf "$VENV_PATH"
        fi

        # Create the venv using the explicit Python path
        "$BASE_PYTHON" -m venv "$VENV_PATH"

        PYTHON_PATH="$VENV_PATH/bin/python"
        PIP_PATH="$VENV_PATH/bin/pip"

        # Add bin to PATH (prepended in subsequent steps)
        echo "$VENV_PATH/bin" >> $GITHUB_PATH

        # Upgrade pip
        "$PYTHON_PATH" -m pip install --upgrade pip

        echo "venv-path=$VENV_PATH" >> $GITHUB_OUTPUT
        echo "python-path=$PYTHON_PATH" >> $GITHUB_OUTPUT

        echo "Virtual environment created successfully!"
        echo "Venv Python location:"
        "$PYTHON_PATH" -c "import sys; print(sys.executable)"
        "$PYTHON_PATH" --version

    - name: Install requirements file (Windows)
      if: inputs.requirements-file != '' && runner.os == 'Windows'
      shell: powershell
      run: |
        $VENV_PATH = "${{ steps.create-venv-windows.outputs.venv-path }}"
        $PIP = "$VENV_PATH\Scripts\pip.exe"

        Write-Host "Installing requirements from ${{ inputs.requirements-file }}..."
        & $PIP install -r "${{ inputs.requirements-file }}"

    - name: Install requirements file (Linux/macOS)
      if: inputs.requirements-file != '' && runner.os != 'Windows'
      shell: bash
      run: |
        VENV_PATH="${{ steps.create-venv-linux.outputs.venv-path }}"
        PIP="$VENV_PATH/bin/pip"

        echo "Installing requirements from ${{ inputs.requirements-file }}..."
        "$PIP" install -r "${{ inputs.requirements-file }}"

    - name: Install package (Windows)
      if: inputs.install-package != '' && runner.os == 'Windows'
      shell: powershell
      run: |
        $VENV_PATH = "${{ steps.create-venv-windows.outputs.venv-path }}"
        $PIP = "$VENV_PATH\Scripts\pip.exe"

        $EXTRA_INDEX = ""
        if ("${{ inputs.extra-index-url }}" -ne "") {
          $EXTRA_INDEX = "--extra-index-url ${{ inputs.extra-index-url }}"
        }

        Write-Host "Installing package: ${{ inputs.install-package }}..."
        $cmd = "$PIP install ${{ inputs.install-package }} $EXTRA_INDEX"
        Invoke-Expression $cmd

    - name: Install package (Linux/macOS)
      if: inputs.install-package != '' && runner.os != 'Windows'
      shell: bash
      run: |
        VENV_PATH="${{ steps.create-venv-linux.outputs.venv-path }}"
        PIP="$VENV_PATH/bin/pip"

        EXTRA_INDEX=""
        if [ -n "${{ inputs.extra-index-url }}" ]; then
          EXTRA_INDEX="--extra-index-url ${{ inputs.extra-index-url }}"
        fi

        echo "Installing package: ${{ inputs.install-package }}..."
        "$PIP" install ${{ inputs.install-package }} $EXTRA_INDEX
