name: Tests

on:
  pull_request:
  push:
    branches:
      - main

concurrency:
  group: ci-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  cpu:
    name: Tests on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ["3.11"]
    steps:
      - uses: actions/checkout@v3
      - name: Free disk space
        if: runner.os == 'Linux'
        run: |
          df -h
          sudo rm -rf /usr/local/lib/android
          sudo rm -rf /usr/share/dotnet
          sudo rm -rf /opt/ghc
          sudo rm -rf /opt/hostedtoolcache
          sudo apt-get clean
          sudo apt-get autoremove -y
          docker system prune -af || true
          df -h
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: "${{ matrix.python-version }}"
      - uses: actions/setup-go@v5
        with:
          go-version: ">=1.17.0"
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.x'
      - name: Ensure cached directory exist before calling cache-related actions
        shell: bash
        run: |
          mkdir -p $HOME/.serena/language_servers/static
          mkdir -p $HOME/.cache/go-build
          mkdir -p $HOME/go/bin
      - name: Install uv
        shell: bash
        run: curl -LsSf https://astral.sh/uv/install.sh | sh
      - name: Cache uv virtualenv
        id: cache-uv
        uses: actions/cache@v3
        with:
          path: .venv
          key: uv-venv-${{ runner.os }}-${{ matrix.python-version }}-lock-${{ hashFiles('uv.lock') }}
      - name: Create virtual environment
        shell: bash
        run: |
          if [ ! -d ".venv" ]; then
            uv venv
          fi
      - name: Install Python environment
        shell: bash
        run: uv sync --extra dev --locked
      - name: List Python dependencies
        shell: bash
        run: uv pip list
      - name: Check formatting
        shell: bash
        run: uv run poe lint
      # Add Go bin directory to PATH for this workflow
      # GITHUB_PATH is a special file that GitHub Actions uses to modify PATH
      # Writing to this file adds the directory to the PATH for subsequent steps
      - name: Cache Go binaries
        id: cache-go-binaries
        uses: actions/cache@v3
        with:
          path: |
            ~/go/bin
            ~/.cache/go-build
          key: go-binaries-${{ runner.os }}-gopls-latest
      - name: Install gopls
        if: steps.cache-go-binaries.outputs.cache-hit != 'true'
        shell: bash
        run: go install golang.org/x/tools/gopls@latest
      - name: Set up Elixir
        if: runner.os != 'Windows'
        uses: erlef/setup-beam@v1
        with:
          elixir-version: "1.19.3"
          otp-version: "28"
#      Erlang currently not tested in CI, random hangings on macos, always hangs on ubuntu
#      In local tests, erlang seems to work though
#      - name: Install Erlang Language Server
#        if: runner.os != 'Windows'
#        shell: bash
#        run: |
#          # Install rebar3 if not already available
#          which rebar3 || (curl -fsSL https://github.com/erlang/rebar3/releases/download/3.23.0/rebar3 -o /tmp/rebar3 && chmod +x /tmp/rebar3 && sudo mv /tmp/rebar3 /usr/local/bin/rebar3)
#          # Clone and build erlang_ls
#          git clone https://github.com/erlang-ls/erlang_ls.git /tmp/erlang_ls
#          cd /tmp/erlang_ls
#          make install PREFIX=/usr/local
#          # Ensure erlang_ls is in PATH
#          echo "$HOME/.local/bin" >> $GITHUB_PATH
      - name: Install clojure tools
        uses: DeLaGuardo/setup-clojure@13.4
        with:
          cli: latest
      - name: Install ccls (C/C++ Language Server)
        shell: bash
        run: |
          if [[ "${{ runner.os }}" == "Linux" ]]; then
            sudo apt-get update
            sudo apt-get install -y ccls
          elif [[ "${{ runner.os }}" == "macOS" ]]; then
            brew install ccls
          elif [[ "${{ runner.os }}" == "Windows" ]]; then
            choco install ccls -y
          fi
          # Verify installation
          if command -v ccls &> /dev/null; then
            echo "ccls installed: $(ccls --version 2>&1 | head -1)"
          else
            echo "ERROR: ccls installation failed"
            exit 1
          fi
      - name: Setup Java (for JVM based languages)
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      - name: Setup .NET SDK (for F# and C# languages)
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '10.0.x'
      - name: List .NET runtimes
        shell: bash
        run: dotnet --list-runtimes
      - name: Install Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: "1.5.0"
          terraform_wrapper: false
      # - name: Install swift
      #   if: runner.os != 'Windows'
      #   uses: swift-actions/setup-swift@v2
      # Installation of swift with the action screws with installation of ruby on macOS for some reason
      # We can try again when version 3 of the action is released, where they will also use swiftly
      # Until then, we use custom code to install swift. Sourcekit-lsp is installed automatically with swift
      - name: Install Swift with swiftly (macOS)
        if: runner.os == 'macOS'
        run: |
          echo "=== Installing swiftly on macOS ==="
          curl -O https://download.swift.org/swiftly/darwin/swiftly.pkg && \
          installer -pkg swiftly.pkg -target CurrentUserHomeDirectory && \
          ~/.swiftly/bin/swiftly init --quiet-shell-followup && \
          . "${SWIFTLY_HOME_DIR:-$HOME/.swiftly}/env.sh" && \
          hash -r
          swiftly install --use 6.1.2
          swiftly use 6.1.2
          echo "~/.swiftly/bin" >> $GITHUB_PATH
          echo "Swiftly installed successfully"
          # Verify sourcekit-lsp is working before proceeding
          echo "=== Verifying sourcekit-lsp installation ==="
          which sourcekit-lsp || echo "Warning: sourcekit-lsp not found in PATH"
          sourcekit-lsp --help || echo "Warning: sourcekit-lsp not responding"
      - name: Install Swift with swiftly (Ubuntu)
        if: runner.os == 'Linux'
        run: |
          echo "=== Installing swiftly on Ubuntu ==="
          # Install dependencies BEFORE Swift to avoid exit code 1
          sudo apt-get update
          sudo apt-get -y install libcurl4-openssl-dev
          curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz && \
          tar zxf swiftly-$(uname -m).tar.gz && \
          ./swiftly init --quiet-shell-followup && \
          . "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh" && \
          hash -r
          swiftly install --use 6.1.2
          swiftly use 6.1.2
          echo "=== Adding Swift toolchain to PATH ==="
          echo "$HOME/.local/share/swiftly/bin" >> $GITHUB_PATH
          echo "Swiftly installed successfully!"
          # Verify sourcekit-lsp is working before proceeding
          echo "=== Verifying sourcekit-lsp installation ==="
          which sourcekit-lsp || echo "Warning: sourcekit-lsp not found in PATH"
          sourcekit-lsp --help || echo "Warning: sourcekit-lsp not responding"
      - name: Install Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.4'
      - name: Install Ruby language server
        shell: bash
        run: gem install ruby-lsp
      - name: Install OCaml and opam
        uses: ocaml/setup-ocaml@v3
        with:
          ocaml-compiler: ${{ runner.os == 'Windows' && '4.14' || '5.3.x' }}
          dune-cache: true
          opam-repositories: |
            ${{ runner.os == 'Windows' && 'opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset' || '' }}
            default: https://github.com/ocaml/opam-repository.git
      - name: Install OCaml packages
        shell: bash
        run: |
          if [ "$RUNNER_OS" = "Windows" ]; then
            opam install -y dune ocaml-lsp-server
          else
            # Require ocaml-lsp-server >= 1.23.0 for cross-file reference support
            opam install -y dune 'ocaml-lsp-server>=1.23.0'
          fi
      - name: Install R
        uses: r-lib/actions/setup-r@v2
        with:
          r-version: '4.4.2'
          use-public-rspm: true
      - name: Install R language server
        shell: bash
        run: |
          Rscript -e "install.packages('languageserver', repos='https://cloud.r-project.org')"
      - name: Set up Julia
        uses: julia-actions/setup-julia@v2
        with:
          version: '1.10'
      - name: Install Julia LanguageServer
        shell: bash
        run: julia -e 'using Pkg; Pkg.add("LanguageServer")'
      - name: Setup Haskell toolchain
        if: runner.os != 'Windows'
        uses: haskell/ghcup-setup@v1
        with:
          ghc: '9.12.2'
          cabal: '3.10.3.0'
          hls: '2.11.0.0'
      - name: Verify Haskell tools
        if: runner.os != 'Windows'
        run: |
          echo "Verifying installed Haskell tools:"
          which ghc && ghc --version
          which cabal && cabal --version
          # HLS verification - non-blocking in case of version incompatibility
          if command -v haskell-language-server-wrapper &>/dev/null; then
            echo "Found haskell-language-server-wrapper"
            haskell-language-server-wrapper --version || echo "WARNING: HLS wrapper found but version check failed"
          elif command -v haskell-language-server &>/dev/null; then
            echo "Found haskell-language-server"
            haskell-language-server --version || echo "WARNING: HLS found but version check failed"
          else
            echo "WARNING: HLS not found (may be incompatible with GHC 9.12.2)"
            echo "This is not a critical error - tests will use HLS if available at runtime"
          fi
        shell: bash
      - name: Pre-build Haskell test project for HLS
        if: runner.os != 'Windows'
        run: |
          cd test/resources/repos/haskell/test_repo
          cabal update
          cabal build --only-dependencies
          cabal build
          echo "Haskell test project built successfully"
        shell: bash
      - name: Install Zig
        uses: goto-bus-stop/setup-zig@v2
        with:
          version: 0.14.1
      - name: Install ZLS (Zig Language Server)
        shell: bash
        run: |
          if [[ "${{ runner.os }}" == "Linux" ]]; then
            wget https://github.com/zigtools/zls/releases/download/0.14.0/zls-x86_64-linux.tar.xz
            tar -xf zls-x86_64-linux.tar.xz
            sudo mv zls /usr/local/bin/
            rm zls-x86_64-linux.tar.xz
          elif [[ "${{ runner.os }}" == "macOS" ]]; then
            wget https://github.com/zigtools/zls/releases/download/0.14.0/zls-x86_64-macos.tar.xz
            tar -xf zls-x86_64-macos.tar.xz
            sudo mv zls /usr/local/bin/
            rm zls-x86_64-macos.tar.xz
          elif [[ "${{ runner.os }}" == "Windows" ]]; then
            curl -L -o zls.zip https://github.com/zigtools/zls/releases/download/0.14.0/zls-x86_64-windows.zip
            unzip -o zls.zip
            mkdir -p "$HOME/bin"
            mv zls.exe "$HOME/bin/"
            echo "$HOME/bin" >> $GITHUB_PATH
            rm zls.zip
          fi
      - name: Install verible-verilog-ls (SystemVerilog Language Server)
        shell: bash
        run: |
          VERIBLE_VERSION="v0.0-4051-g9fdb4057"

          if [[ "${{ runner.os }}" == "Linux" ]]; then
            wget https://github.com/chipsalliance/verible/releases/download/${VERIBLE_VERSION}/verible-${VERIBLE_VERSION}-linux-static-x86_64.tar.gz
            tar -xzf verible-${VERIBLE_VERSION}-linux-static-x86_64.tar.gz
            sudo mv verible-${VERIBLE_VERSION}/bin/verible-verilog-ls /usr/local/bin/
            rm -rf verible-${VERIBLE_VERSION} verible-${VERIBLE_VERSION}-linux-static-x86_64.tar.gz
          elif [[ "${{ runner.os }}" == "macOS" ]]; then
            wget https://github.com/chipsalliance/verible/releases/download/${VERIBLE_VERSION}/verible-${VERIBLE_VERSION}-macOS.tar.gz
            tar -xzf verible-${VERIBLE_VERSION}-macOS.tar.gz
            sudo mv verible-${VERIBLE_VERSION}-macOS/bin/verible-verilog-ls /usr/local/bin/
            rm -rf verible-${VERIBLE_VERSION}-macOS verible-${VERIBLE_VERSION}-macOS.tar.gz
          elif [[ "${{ runner.os }}" == "Windows" ]]; then
            curl -L -o verible.zip https://github.com/chipsalliance/verible/releases/download/${VERIBLE_VERSION}/verible-${VERIBLE_VERSION}-win64.zip
            unzip -o verible.zip
            mkdir -p "$HOME/bin"
            mv verible-${VERIBLE_VERSION}-win64/verible-verilog-ls.exe "$HOME/bin/"
            echo "$HOME/bin" >> $GITHUB_PATH
            rm -rf verible-${VERIBLE_VERSION}-win64 verible.zip
          fi

          # Verify installation
          if command -v verible-verilog-ls &> /dev/null; then
            echo "verible-verilog-ls installed successfully"
          else
            echo "WARNING: verible-verilog-ls not found in PATH"
          fi
      - name: Install Lua Language Server
        shell: bash
        run: |
          LUA_LS_VERSION="3.15.0"
          LUA_LS_DIR="$HOME/.serena/language_servers/lua"
          mkdir -p "$LUA_LS_DIR"
          
          if [[ "${{ runner.os }}" == "Linux" ]]; then
            if [[ "$(uname -m)" == "x86_64" ]]; then
              wget https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-linux-x64.tar.gz
              tar -xzf lua-language-server-${LUA_LS_VERSION}-linux-x64.tar.gz -C "$LUA_LS_DIR"
            else
              wget https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-linux-arm64.tar.gz
              tar -xzf lua-language-server-${LUA_LS_VERSION}-linux-arm64.tar.gz -C "$LUA_LS_DIR"
            fi
            chmod +x "$LUA_LS_DIR/bin/lua-language-server"
            # Create wrapper script instead of symlink to ensure supporting files are found
            echo '#!/bin/bash' | sudo tee /usr/local/bin/lua-language-server > /dev/null
            echo 'cd "${HOME}/.serena/language_servers/lua/bin"' | sudo tee -a /usr/local/bin/lua-language-server > /dev/null
            echo 'exec ./lua-language-server "$@"' | sudo tee -a /usr/local/bin/lua-language-server > /dev/null
            sudo chmod +x /usr/local/bin/lua-language-server
            rm lua-language-server-*.tar.gz
          elif [[ "${{ runner.os }}" == "macOS" ]]; then
            if [[ "$(uname -m)" == "x86_64" ]]; then
              wget https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-darwin-x64.tar.gz
              tar -xzf lua-language-server-${LUA_LS_VERSION}-darwin-x64.tar.gz -C "$LUA_LS_DIR"
            else
              wget https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-darwin-arm64.tar.gz
              tar -xzf lua-language-server-${LUA_LS_VERSION}-darwin-arm64.tar.gz -C "$LUA_LS_DIR"
            fi
            chmod +x "$LUA_LS_DIR/bin/lua-language-server"
            # Create wrapper script instead of symlink to ensure supporting files are found
            echo '#!/bin/bash' | sudo tee /usr/local/bin/lua-language-server > /dev/null
            echo 'cd "${HOME}/.serena/language_servers/lua/bin"' | sudo tee -a /usr/local/bin/lua-language-server > /dev/null
            echo 'exec ./lua-language-server "$@"' | sudo tee -a /usr/local/bin/lua-language-server > /dev/null
            sudo chmod +x /usr/local/bin/lua-language-server
            rm lua-language-server-*.tar.gz
          elif [[ "${{ runner.os }}" == "Windows" ]]; then
            curl -L -o lua-ls.zip https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-win32-x64.zip
            unzip -o lua-ls.zip -d "$LUA_LS_DIR"
            # For Windows, we'll add the bin directory directly to PATH
            # The lua-language-server.exe can find its supporting files relative to its location
            echo "$LUA_LS_DIR/bin" >> $GITHUB_PATH
            rm lua-ls.zip
          fi
      - name: Install Perl::LanguageServer
        if: runner.os != 'Windows'
        shell: bash
        run: |
          if [[ "${{ runner.os }}" == "Linux" ]]; then
            sudo apt-get update
            sudo apt-get install -y cpanminus build-essential libanyevent-perl libio-aio-perl
          elif [[ "${{ runner.os }}" == "macOS" ]]; then
            brew install cpanminus
          fi
          PERL_MM_USE_DEFAULT=1 cpanm --notest --force Perl::LanguageServer
          # Set up Perl local::lib environment for subsequent steps
          echo "PERL5LIB=$HOME/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}" >> $GITHUB_ENV
          echo "PERL_LOCAL_LIB_ROOT=$HOME/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}" >> $GITHUB_ENV
          echo "PERL_MB_OPT=--install_base \"$HOME/perl5\"" >> $GITHUB_ENV
          echo "PERL_MM_OPT=INSTALL_BASE=$HOME/perl5" >> $GITHUB_ENV
          echo "$HOME/perl5/bin" >> $GITHUB_PATH
      - name: Install ansible-core and ansible-lint (for Ansible language server tests)
        shell: bash
        run: uv run pip install ansible-core ansible-lint
      - name: Install Elm
        shell: bash
        run: npm install -g elm@0.19.1-6
      - name: Install Nix
        if: runner.os != 'Windows'  # Nix doesn't support Windows natively
        uses: cachix/install-nix-action@v30
        with:
          nix_path: nixpkgs=channel:nixos-unstable
      - name: Install nixd (Nix Language Server)
        if: runner.os != 'Windows'  # Skip on Windows since Nix isn't available
        shell: bash
        run: |
          # Install nixd using nix
          nix profile install github:nix-community/nixd

          # Verify nixd is installed and working
          if ! command -v nixd &> /dev/null; then
            echo "nixd installation failed or not in PATH"
            exit 1
          fi

          echo "$HOME/.nix-profile/bin" >> $GITHUB_PATH
      - name: Verify Nix package build
        if: runner.os != 'Windows'  # Nix only supported on Linux/macOS
        shell: bash
        run: |
          # Verify the flake builds successfully
          nix build --no-link
      - name: Install Regal (Rego Language Server)
        shell: bash
        run: |
          REGAL_VERSION="0.39.0"

          if [[ "${{ runner.os }}" == "Linux" ]]; then
            if [[ "$(uname -m)" == "x86_64" ]]; then
              curl -L -o regal https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Linux_x86_64
            else
              curl -L -o regal https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Linux_arm64
            fi
            chmod +x regal
            sudo mv regal /usr/local/bin/
          elif [[ "${{ runner.os }}" == "macOS" ]]; then
            if [[ "$(uname -m)" == "x86_64" ]]; then
              curl -L -o regal https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Darwin_x86_64
            else
              curl -L -o regal https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Darwin_arm64
            fi
            chmod +x regal
            sudo mv regal /usr/local/bin/
          elif [[ "${{ runner.os }}" == "Windows" ]]; then
            curl -L -o regal.exe https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Windows_x86_64.exe
            mkdir -p "$HOME/bin"
            mv regal.exe "$HOME/bin/"
            echo "$HOME/bin" >> $GITHUB_PATH
          fi
      - name: Install Free Pascal Compiler
        shell: bash
        run: |
          if [[ "${{ runner.os }}" == "Linux" ]]; then
            sudo apt-get update
            sudo apt-get install -y fpc fpc-source
            # Set environment variables for pasls
            echo "PP=/usr/bin/fpc" >> $GITHUB_ENV
            # Find FPC source directory (version may vary) - remove trailing slash
            FPCDIR=$(ls -d /usr/share/fpcsrc/*/ 2>/dev/null | head -1 | sed 's:/$::')
            if [[ -z "$FPCDIR" ]]; then
              FPCDIR="/usr/share/fpcsrc"
            fi
            echo "FPCDIR=$FPCDIR" >> $GITHUB_ENV
            echo "=== FPC source directory structure ==="
            ls -la "$FPCDIR" || echo "FPCDIR not found"
            ls -la "$FPCDIR/rtl" 2>/dev/null || echo "rtl subdirectory not found"
          elif [[ "${{ runner.os }}" == "macOS" ]]; then
            brew install fpc
            # Download FPC source from SourceForge (fpc-src-laz cask is incompatible with ARM64)
            FPC_VERSION="3.2.2"
            curl -L -o fpc-source.tar.gz "https://sourceforge.net/projects/freepascal/files/Source/${FPC_VERSION}/fpc-${FPC_VERSION}.source.tar.gz/download"
            mkdir -p "$HOME/fpcsrc"
            tar -xzf fpc-source.tar.gz -C "$HOME/fpcsrc"
            rm fpc-source.tar.gz
            # Check extracted directory structure (might be nested)
            echo "=== Extracted FPC source structure ==="
            ls -la "$HOME/fpcsrc"
            # Find the actual FPC source root (contains rtl, packages, etc.)
            if [[ -d "$HOME/fpcsrc/fpc-${FPC_VERSION}/rtl" ]]; then
              FPCDIR="$HOME/fpcsrc/fpc-${FPC_VERSION}"
            elif [[ -d "$HOME/fpcsrc/fpc-${FPC_VERSION}/fpc-${FPC_VERSION}/rtl" ]]; then
              FPCDIR="$HOME/fpcsrc/fpc-${FPC_VERSION}/fpc-${FPC_VERSION}"
            else
              FPCDIR="$HOME/fpcsrc/fpc-${FPC_VERSION}"
            fi
            echo "PP=$(which fpc)" >> $GITHUB_ENV
            echo "FPCDIR=$FPCDIR" >> $GITHUB_ENV
            echo "=== FPC source directory ==="
            ls -la "$FPCDIR" || echo "FPCDIR not found"
          elif [[ "${{ runner.os }}" == "Windows" ]]; then
            FPC_VERSION="3.2.2"
            # Download freepascal-ootb (includes FPC compiler)
            curl -L -o fpc-ootb.zip https://github.com/fredvs/freepascal-ootb/releases/download/${FPC_VERSION}/fpc-ootb-322-x86_64-win64.zip
            mkdir -p "$HOME/fpc"
            unzip -q fpc-ootb.zip -d "$HOME/fpc"
            rm fpc-ootb.zip
            # Download FPC source from SourceForge (fpc-ootb only has compiled units, not source)
            curl -L -o fpc-source.zip "https://sourceforge.net/projects/freepascal/files/Source/${FPC_VERSION}/fpc-${FPC_VERSION}.source.zip/download"
            mkdir -p "$HOME/fpcsrc"
            unzip -q fpc-source.zip -d "$HOME/fpcsrc"
            rm fpc-source.zip
            # Find fpc executable (fpc-ootb uses fpc-ootb.exe as the compiler)
            echo "=== FPC directory structure ==="
            find "$HOME/fpc" -name "*.exe" -type f 2>/dev/null | head -10
            FPC_EXE=$(find "$HOME/fpc" -name "fpc-ootb-64.exe" -type f 2>/dev/null | head -1)
            echo "Found FPC executable: $FPC_EXE"
            echo "Found FPC source dir: $HOME/fpcsrc/fpc-${FPC_VERSION}"
            # Set environment variables for pasls
            echo "PP=$FPC_EXE" >> $GITHUB_ENV
            echo "FPCDIR=$HOME/fpcsrc/fpc-${FPC_VERSION}" >> $GITHUB_ENV
            # Add FPC bin directory to PATH
            FPC_BIN_DIR=$(dirname "$FPC_EXE")
            echo "$FPC_BIN_DIR" >> $GITHUB_PATH
          fi
      - name: Verify FPC installation
        shell: bash
        run: |
          echo "=== Environment variables ==="
          echo "PP=$PP"
          echo "FPCDIR=$FPCDIR"

          # Create a simple test program
          if [[ "${{ runner.os }}" == "Windows" ]]; then
            TEST_PAS="$TEMP/fpc_test.pas"
            TEST_OUT="$TEMP/fpc_test"
          else
            TEST_PAS="/tmp/fpc_test.pas"
            TEST_OUT="/tmp/fpc_test"
          fi
          echo "program fpc_test; begin writeln('FPC works'); end." > "$TEST_PAS"

          # Compile using PP (the compiler we actually use in tests)
          echo "=== Compiling test program with PP=$PP ==="
          if [[ -n "$PP" ]]; then
            "$PP" "$TEST_PAS" -o"$TEST_OUT" 2>&1
          else
            echo "ERROR: PP environment variable is not set"
            exit 1
          fi

          # Verify output binary exists
          if [[ -f "$TEST_OUT" ]] || [[ -f "${TEST_OUT}.exe" ]]; then
            echo "FPC compilation test PASSED"
          else
            echo "ERROR: FPC compilation failed - no output binary at $TEST_OUT"
            exit 1
          fi

          # Verify FPCDIR exists (required for pasls)
          if [[ -d "$FPCDIR" ]]; then
            echo "FPCDIR exists: $FPCDIR"
          else
            echo "ERROR: FPCDIR does not exist: $FPCDIR"
            exit 1
          fi
      - name: Build Lean 4 test project
        uses: leanprover/lean-action@v1
        with:
          lake-package-directory: test/resources/repos/lean4/test_repo
      - name: Cache language servers
        id: cache-language-servers
        uses: actions/cache@v3
        with:
          path: ~/.serena/language_servers/static
          key: language-servers-${{ runner.os }}-v1
          restore-keys: |
            language-servers-${{ runner.os }}-
      - name: Report free disk space
        if: runner.os == 'Linux'
        run: |
          echo "Free disk space before tests:"
          df -h
      - name: Test with pytest
        shell: bash
        run: uv run poe test -q --tb=short
      - name: Type-checking with mypy
        shell: bash
        run: uv run poe type-check
