name: CI

on:
  push:
    branches: [ master, dev, ci_testing, experiments ]
  pull_request:
    branches: [ master, dev ]

env:
  LLVM_RELEASE_VERSION_WINDOWS: 18
  LLVM_RELEASE_VERSION_MAC: 17
  LLVM_RELEASE_VERSION_LINUX: 17
  LLVM_RELEASE_VERSION_OPENBSD: 19
  LLVM_RELEASE_VERSION_UBUNTU22: 17
  LLVM_DEV_VERSION: 22
jobs:

  build-msvc:
    runs-on: windows-latest
    strategy:
      # Don't abort runners if a single one fails
      fail-fast: false
      matrix:
        build_type: [ Release, Debug ]

    defaults:
      run:
        shell: cmd
    steps:
      - uses: actions/checkout@v4

      - name: CMake
        run: |
          cmake -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
          cmake --build build --config ${{ matrix.build_type }}

      - name: Compile and run some examples
        run: |
          cd resources
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run -L C:\ --print-linking examples\hello_world_many.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run --print-linking examples\time.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run --print-linking examples\fannkuch-redux.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\contextfree\boolerr.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\ls.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\load_world.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\process.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\args.c3 -- foo -bar "baz baz"
          ..\build\${{ matrix.build_type }}\c3c.exe compile --no-entry --test -g -O0 --threads 1 --target macos-x64 examples\constants.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run msvc_stack.c3

      - name: Build testproject
        run: |
          call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
          cd resources/testproject
          ..\..\build\${{ matrix.build_type }}\c3c.exe -vvv --emit-llvm run hello_world_win32 --trust=full
          dir out\llvm\windows-x64
          ..\..\build\${{ matrix.build_type }}\c3c.exe clean
          dir out\llvm\windows-x64


      - name: Build testproject lib
        run: |
          cd resources/testproject
          call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
          ..\..\build\${{ matrix.build_type }}\c3c.exe -vvv build hello_world_win32_lib --trust=full

      - name: Compile and run dynlib-test
        run: |
          cd resources/examples/dynlib-test
          ..\..\..\build\${{ matrix.build_type }}\c3c.exe -vv dynamic-lib add.c3
          ..\..\..\build\${{ matrix.build_type }}\c3c.exe -vv compile-run test.c3 -l ./add.lib          

      - name: Compile and run staticlib-test
        run: |
          cd resources/examples/staticlib-test
          ..\..\..\build\${{ matrix.build_type }}\c3c.exe -vv static-lib add.c3
          ..\..\..\build\${{ matrix.build_type }}\c3c.exe -vv compile-run test.c3 -l ./add.lib          

      - name: Vendor-fetch
        run: |
          build\${{ matrix.build_type }}\c3c.exe vendor-fetch raylib55

      - name: Try raylib5
        run: |
          cd resources
          ..\build\${{ matrix.build_type }}\c3c.exe vendor-fetch raylib55
          ..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_arkanoid.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_snake.c3
          ..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_tetris.c3

      - name: Compile run unit tests
        run: |
          cd test
          ..\build\${{ matrix.build_type }}\c3c.exe compile-test unit -O1 -D SLOW_TESTS

      - name: run compiler tests
        run: |
          cd test
          ..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/ --no-terminal

      - name: Test python script
        run: |
          py msvc_build_libraries.py --accept-license
          dir msvc_sdk

      - name: upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: c3-windows-${{ matrix.build_type }}
          path: |
            build\${{ matrix.build_type }}\c3c.exe
            build\${{ matrix.build_type }}\c3c_rt

  build-msys2-mingw:
    runs-on: windows-latest
    if: ${{ false }}
    strategy:
      # Don't abort runners if a single one fails
      fail-fast: false
      matrix:
        build_type: [Release, Debug]

    defaults:
      run:
        shell: msys2 {0}
    steps:
      - uses: actions/checkout@v4

      - uses: msys2/setup-msys2@v2
        with:
          msystem: MINGW64
          update: true
          install: git binutils mingw-w64-x86_64-clang mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-python
      - shell: msys2 {0}
        run: |
            pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-llvm-20.1.0-1-any.pkg.tar.zst
            pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-lld-20.1.0-1-any.pkg.tar.zst
      - name: CMake
        run: |
          cmake -B build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_LINKER=lld
          cmake --build build

      - name: Compile and run some examples
        run: |
          cd resources
          ../build/c3c compile-run --print-linking examples/hello_world_many.c3
          ../build/c3c compile-run --print-linking examples/process.c3
          ../build/c3c compile-run --print-linking examples/time.c3
          ../build/c3c compile-run --print-linking examples/fannkuch-redux.c3
          ../build/c3c compile-run --print-linking examples/contextfree/boolerr.c3
          ../build/c3c compile-run --print-linking examples/load_world.c3
          ../build/c3c compile-run --print-linking examples/args.c3 -- foo -bar "baz baz"
          ../build/c3c compile --no-entry --test -g -O0 --threads 1 --target macos-x64 examples/constants.c3

      - name: Build testproject
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --trust=full

      - name: Vendor-fetch
        run: |
          ./build/c3c vendor-fetch raylib55

      - name: Build testproject lib
        run: |
          cd resources/testproject
          ../../build/c3c build hello_world_lib --cc cc -vvv --trust=full

      - name: run compiler tests
        run: |
          cd test
          ../build/c3c.exe compile --target windows-x64 -O1 src/test_suite_runner.c3
          ./test_suite_runner.exe ../build/c3c.exe test_suite/ --no-terminal

  build-msys2-clang:
    runs-on: windows-latest
    #if: ${{ false }}
    strategy:
      # Don't abort runners if a single one fails
      fail-fast: false
      matrix:
        build_type: [Release, Debug]

    defaults:
      run:
        shell: msys2 {0}
    steps:
      - uses: actions/checkout@v4

      - uses: msys2/setup-msys2@v2
        with:
          msystem: CLANG64
          update: false
          install: git binutils mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-toolchain mingw-w64-clang-x86_64-python

      - name: CMake
        run: |
          cmake -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
          cmake --build build

      - name: Compile and run some examples
        run: |
          cd resources
          ../build/c3c compile-run examples/hello_world_many.c3
          ../build/c3c compile-run examples/time.c3
          ../build/c3c compile-run examples/fannkuch-redux.c3
          ../build/c3c compile-run examples/contextfree/boolerr.c3
          ../build/c3c compile-run examples/load_world.c3
          ../build/c3c compile-run examples/args.c3 -- foo -bar "baz baz"
          ../build/c3c compile --no-entry --test -g -O0 --threads 1 --target macos-x64 examples/constants.c3
      - name: Build testproject
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --trust=full

      - name: Build testproject lib
        run: |
          cd resources/testproject
          ../../build/c3c build hello_world_lib -vvv --trust=full

      - name: run compiler tests
        run: |
          cd test
          ../build/c3c.exe compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c.exe test_suite/ --no-terminal

  build-linux:
    runs-on: ubuntu-22.04
    strategy:
      # Don't abort runners if a single one fails
      fail-fast: false
      matrix:
        build_type: [Release, Debug]
        llvm_version: [17, 18, 19, 20, 21, 22]

    steps:
      - uses: actions/checkout@v4
      - name: Install common deps
        run: |
          sudo apt-get install zlib1g zlib1g-dev python3 ninja-build curl

      - name: Install Clang ${{matrix.llvm_version}}
        run: |
          wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
          if [[ "${{matrix.llvm_version}}" < 18 ]]; then
            sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${{matrix.llvm_version}} main"
            sudo apt-get update
            sudo apt-get install -y -t llvm-toolchain-focal-${{matrix.llvm_version}} libpolly-${{matrix.llvm_version}}-dev \
              clang-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}}-dev \
              lld-${{matrix.llvm_version}} liblld-${{matrix.llvm_version}}-dev libmlir-${{matrix.llvm_version}} \
              libmlir-${{matrix.llvm_version}}-dev mlir-${{matrix.llvm_version}}-tools
          else
            if [[ "${{matrix.llvm_version}}" < "${{env.LLVM_DEV_VERSION}}" ]]; then
              sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${{matrix.llvm_version}} main"
              sudo apt-get update
              sudo apt-get install -y -t llvm-toolchain-focal-${{matrix.llvm_version}} libpolly-${{matrix.llvm_version}}-dev \
                clang-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}}-dev \
                lld-${{matrix.llvm_version}} liblld-${{matrix.llvm_version}}-dev
            else
              sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main"
              sudo apt-get install -y -t llvm-toolchain-focal libpolly-${{matrix.llvm_version}}-dev \
                clang-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}}-dev \
                lld-${{matrix.llvm_version}} liblld-${{matrix.llvm_version}}-dev
            fi
          fi
      - name: CMake
        if: matrix.llvm_version < 18 || matrix.llvm_version == env.LLVM_DEV_VERSION
        run: |
          cmake -B build \
                -G Ninja \
                -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
                -DCMAKE_C_COMPILER=clang-${{matrix.llvm_version}} \
                -DCMAKE_CXX_COMPILER=clang++-${{matrix.llvm_version}} \
                -DCMAKE_LINKER=lld-link-${{matrix.llvm_version}} \
                -DCMAKE_OBJCOPY=llvm-objcopy-${{matrix.llvm_version}} \
                -DCMAKE_STRIP=llvm-strip-${{matrix.llvm_version}} \
                -DCMAKE_DLLTOOL=llvm-dlltool-${{matrix.llvm_version}} \
                -DLLVM_ENABLE_LIBXML2=OFF \
                -DC3_LLVM_VERSION=${{matrix.llvm_version}}
          cmake --build build
      - name: CMake18
        if: matrix.llvm_version >= 18 && matrix.llvm_version != env.LLVM_DEV_VERSION
        run: |
          cmake -B build \
                -G Ninja \
                -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
                -DCMAKE_C_COMPILER=clang-${{matrix.llvm_version}} \
                -DCMAKE_CXX_COMPILER=clang++-${{matrix.llvm_version}} \
                -DCMAKE_LINKER=lld-link-${{matrix.llvm_version}} \
                -DCMAKE_OBJCOPY=llvm-objcopy-${{matrix.llvm_version}} \
                -DCMAKE_STRIP=llvm-strip-${{matrix.llvm_version}} \
                -DCMAKE_DLLTOOL=llvm-dlltool-${{matrix.llvm_version}} \
                -DLLVM_ENABLE_LIBXML2=OFF \
                -DC3_LLVM_VERSION=${{matrix.llvm_version}}.1
          cmake --build build

      - name: Compile and run some examples
        run: |
          cd resources
          ../build/c3c compile examples/base64.c3
          ../build/c3c compile examples/binarydigits.c3
          ../build/c3c compile examples/brainfk.c3
          ../build/c3c compile examples/factorial_macro.c3
          ../build/c3c compile examples/fasta.c3
          ../build/c3c compile examples/gameoflife.c3
          ../build/c3c compile examples/hash.c3
          ../build/c3c compile-only examples/levenshtein.c3
          ../build/c3c compile examples/load_world.c3
          ../build/c3c compile-only examples/map.c3
          ../build/c3c compile examples/mandelbrot.c3
          ../build/c3c compile examples/plus_minus.c3
          ../build/c3c compile examples/nbodies.c3
          ../build/c3c compile examples/spectralnorm.c3
          ../build/c3c compile examples/swap.c3
          ../build/c3c compile examples/contextfree/boolerr.c3
          ../build/c3c compile examples/contextfree/dynscope.c3
          ../build/c3c compile examples/contextfree/guess_number.c3
          ../build/c3c compile examples/contextfree/multi.c3
          ../build/c3c compile examples/contextfree/cleanup.c3
          ../build/c3c compile-run examples/hello_world_many.c3
          ../build/c3c compile-run examples/time.c3
          ../build/c3c compile-run examples/fannkuch-redux.c3
          ../build/c3c compile-run examples/contextfree/boolerr.c3
          ../build/c3c compile-run examples/load_world.c3
          ../build/c3c compile-run examples/process.c3
          ../build/c3c compile-run examples/ls.c3
          ../build/c3c compile-run --linker=builtin linux_stack.c3
          ../build/c3c compile-run linux_stack.c3
          ../build/c3c compile-run examples/args.c3 -- foo -bar "baz baz"

      - name: Compile and run dynlib-test
        run: |
          cd resources/examples/dynlib-test
          ../../../build/c3c -vv dynamic-lib add.c3
          mv add.so libadd.so
          cc test.c -L. -ladd -Wl,-rpath=.         
          ./a.out
          ../../../build/c3c compile-run test.c3 -L . -l add -z -Wl,-rpath=.           

      - name: Compile and run staticlib-test
        run: |
          cd resources/examples/staticlib-test
          ../../../build/c3c -vv static-lib add.c3
          mv add.a libadd.a
          cc test.c -L. -ladd         
          ./a.out
          ../../../build/c3c compile-run test.c3 -L . -l add           

      - name: Compile run unit tests
        run: |
          cd test
          ../build/c3c compile-test unit -D SLOW_TESTS

      - name: Build testproject
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --trust=full

      - name: Test WASM
        run: |
          cd resources/testfragments
          ../../build/c3c compile --target wasm32 -g0 --no-entry -Os wasm4.c3

      - name: Install QEMU and Risc-V toolchain
        run: |
          sudo apt-get install opensbi qemu-system-misc u-boot-qemu gcc-riscv64-unknown-elf

      - name: Compile and run Baremetal Risc-V Example
        run: |
          cd resources/examples/embedded/riscv-qemu
          make C3C_PATH=../../../../build/ run

      - name: Build testproject direct linker
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --linker=builtin --trust=full

      - name: Init a library & a project
        run: |
          ./build/c3c init-lib mylib
          ls mylib.c3l
          ./build/c3c init myproject
          ls myproject

      - name: run compiler tests
        run: |
          cd test
          ../build/c3c compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c  test_suite/

      - name: bundle_output
        if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_LINUX
        run: |
          mkdir c3
          cp -r lib c3
          cp msvc_build_libraries.py c3
          cp build/c3c c3
          cp README.md c3
          cp releasenotes.md c3
          tar czf c3-linux-${{matrix.build_type}}.tar.gz c3

      - name: upload artifacts
        if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_LINUX
        uses: actions/upload-artifact@v4
        with:
          name: c3-linux-${{matrix.build_type}}
          path: c3-linux-${{matrix.build_type}}.tar.gz

  build-linux-ubuntu22:
    runs-on: ubuntu-22.04
    strategy:
      # Don't abort runners if a single one fails
      fail-fast: false
      matrix:
        build_type: [Release, Debug]
        llvm_version: [17, 18, 19, 20]
    steps:
      - uses: actions/checkout@v4
      - name: Install common deps
        run: |
          sudo apt-get install zlib1g zlib1g-dev python3 ninja-build curl

      - name: Install Clang ${{matrix.llvm_version}}
        run: |
          wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
          if [[ "${{matrix.llvm_version}}" < "${{env.LLVM_DEV_VERSION}}" ]]; then
            sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${{matrix.llvm_version}} main"
          else
            sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main"
          fi
          sudo apt-get update
          sudo apt-get install -y clang-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}}-dev lld-${{matrix.llvm_version}} liblld-${{matrix.llvm_version}}-dev
          sudo apt-get install -y libmlir-${{matrix.llvm_version}} libmlir-${{matrix.llvm_version}}-dev mlir-${{matrix.llvm_version}}-tools
          sudo apt-get install -y libpolly-${{matrix.llvm_version}}-dev
      - name: CMake Old
        if: matrix.llvm_version < 18 || matrix.llvm_version == env.LLVM_DEV_VERSION
        run: |
          cmake -B build \
                -G Ninja \
                -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
                -DCMAKE_C_COMPILER=clang-${{matrix.llvm_version}} \
                -DCMAKE_CXX_COMPILER=clang++-${{matrix.llvm_version}} \
                -DCMAKE_LINKER=lld-link-${{matrix.llvm_version}} \
                -DCMAKE_OBJCOPY=llvm-objcopy-${{matrix.llvm_version}} \
                -DCMAKE_STRIP=llvm-strip-${{matrix.llvm_version}} \
                -DCMAKE_DLLTOOL=llvm-dlltool-${{matrix.llvm_version}} \
                -DLLVM_ENABLE_LIBXML2=OFF \
                -DC3_LLVM_VERSION=${{matrix.llvm_version}}
          cmake --build build
      - name: CMake
        if: matrix.llvm_version >= 18 && matrix.llvm_version != env.LLVM_DEV_VERSION
        run: |
          cmake -B build \
                -G Ninja \
                -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
                -DCMAKE_C_COMPILER=clang-${{matrix.llvm_version}} \
                -DCMAKE_CXX_COMPILER=clang++-${{matrix.llvm_version}} \
                -DCMAKE_LINKER=lld-link-${{matrix.llvm_version}} \
                -DCMAKE_OBJCOPY=llvm-objcopy-${{matrix.llvm_version}} \
                -DCMAKE_STRIP=llvm-strip-${{matrix.llvm_version}} \
                -DCMAKE_DLLTOOL=llvm-dlltool-${{matrix.llvm_version}} \
                -DLLVM_ENABLE_LIBXML2=OFF \
                -DC3_LLVM_VERSION=${{matrix.llvm_version}}.1
          cmake --build build
      - name: Compile and run some examples
        run: |
          cd resources
          ../build/c3c compile examples/gameoflife.c3
          ../build/c3c compile-only examples/levenshtein.c3
          ../build/c3c compile-only examples/map.c3
          ../build/c3c compile examples/mandelbrot.c3
          ../build/c3c compile examples/plus_minus.c3
          ../build/c3c compile examples/spectralnorm.c3
          ../build/c3c compile examples/swap.c3
          ../build/c3c compile examples/contextfree/guess_number.c3
          ../build/c3c compile-run examples/hash.c3
          ../build/c3c compile-run examples/nbodies.c3
          ../build/c3c compile-run examples/contextfree/boolerr.c3
          ../build/c3c compile-run examples/contextfree/dynscope.c3
          ../build/c3c compile-run examples/contextfree/multi.c3
          ../build/c3c compile-run examples/contextfree/cleanup.c3
          ../build/c3c compile-run examples/hello_world_many.c3
          ../build/c3c compile-run examples/time.c3
          ../build/c3c compile-run examples/fannkuch-redux.c3
          ../build/c3c compile-run examples/load_world.c3
          ../build/c3c compile-run examples/base64.c3
          ../build/c3c compile-run examples/binarydigits.c3
          ../build/c3c compile-run examples/brainfk.c3
          ../build/c3c compile-run examples/factorial_macro.c3
          ../build/c3c compile-run examples/fasta.c3
          ../build/c3c compile-run examples/process.c3
          ../build/c3c compile-run --linker=builtin linux_stack.c3
          ../build/c3c compile-run linux_stack.c3
          ../build/c3c compile-run examples/args.c3 -- foo -bar "baz baz"

      - name: Compile run unit tests
        run: |
          cd test
          ../build/c3c compile-test unit --sanitize=address -D SLOW_TESTS

      - name: Build testproject
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --trust=full

      - name: Build testproject direct linker
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --linker=builtin --trust=full

      - name: run compiler tests
        run: |
          cd test
          ../build/c3c compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c test_suite/

      - name: bundle_output
        if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_UBUNTU22
        run: |
          mkdir c3
          cp -r lib c3
          cp README.md c3
          cp releasenotes.md c3          
          cp msvc_build_libraries.py c3
          cp build/c3c c3
          tar czf c3-ubuntu-22-${{matrix.build_type}}.tar.gz c3

      - name: upload artifacts
        if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_UBUNTU22
        uses: actions/upload-artifact@v4
        with:
          name: c3-ubuntu-22-${{matrix.build_type}}
          path: c3-ubuntu-22-${{matrix.build_type}}.tar.gz

  build-with-docker:
    runs-on: ubuntu-22.04
    strategy:
      fail-fast: false
      matrix:
        ubuntu_version: [20.04, 22.04]
        build_type: [Release, Debug]
        llvm_version: [17, 18, 19]

    steps:
      - uses: actions/checkout@v4

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Make script executable
        run: chmod +x ./build-with-docker.sh

      - name: Run build
        run: |
          LLVM_VERSION=${{ matrix.llvm_version }} UBUNTU_VERSION=${{ matrix.ubuntu_version }} CMAKE_BUILD_TYPE=${{ matrix.build_type }} ./build-with-docker.sh
      
      - name: Compile and run some examples
        run: |
          cd resources
          ../build/c3c compile examples/base64.c3
          ../build/c3c compile examples/binarydigits.c3
          ../build/c3c compile examples/brainfk.c3
          ../build/c3c compile examples/factorial_macro.c3
          ../build/c3c compile examples/fasta.c3
          ../build/c3c compile examples/gameoflife.c3
          ../build/c3c compile examples/hash.c3
          ../build/c3c compile-only examples/levenshtein.c3
          ../build/c3c compile examples/load_world.c3
          ../build/c3c compile-only examples/map.c3
          ../build/c3c compile examples/mandelbrot.c3
          ../build/c3c compile examples/plus_minus.c3
          ../build/c3c compile examples/nbodies.c3
          ../build/c3c compile examples/spectralnorm.c3
          ../build/c3c compile examples/swap.c3
          ../build/c3c compile examples/contextfree/boolerr.c3
          ../build/c3c compile examples/contextfree/dynscope.c3
          ../build/c3c compile examples/contextfree/guess_number.c3
          ../build/c3c compile examples/contextfree/multi.c3
          ../build/c3c compile examples/contextfree/cleanup.c3
          ../build/c3c compile-run examples/hello_world_many.c3
          ../build/c3c compile-run examples/time.c3
          ../build/c3c compile-run examples/fannkuch-redux.c3
          ../build/c3c compile-run examples/contextfree/boolerr.c3
          ../build/c3c compile-run examples/load_world.c3
          ../build/c3c compile-run examples/process.c3
          ../build/c3c compile-run examples/ls.c3
          ../build/c3c compile-run --linker=builtin linux_stack.c3
          ../build/c3c compile-run linux_stack.c3
          ../build/c3c compile-run examples/args.c3 -- foo -bar "baz baz"

      - name: Compile run unit tests
        run: |
          cd test
          ../build/c3c compile-test unit -D SLOW_TESTS

      - name: Build testproject
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --trust=full

      - name: Test WASM
        run: |
          cd resources/testfragments
          ../../build/c3c compile --reloc=none --target wasm32 -g0 --no-entry -Os wasm4.c3

      - name: Build testproject direct linker
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --linker=builtin --trust=full

      - name: Init a library & a project
        run: |
          ./build/c3c init-lib mylib
          ls mylib.c3l
          ./build/c3c init myproject
          ls myproject

      - name: run compiler tests
        run: |
          cd test
          ../build/c3c compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c test_suite/

  build-mac:
    runs-on: macos-latest
    strategy:
      # Don't abort runners if a single one fails
      fail-fast: false
      matrix:
        build_type: [Release, Debug]
        llvm_version: [17, 18]
    steps:
      - uses: actions/checkout@v4
      - name: Download LLVM
        run: |
          brew install llvm@${{ matrix.llvm_version }} ninja curl
          echo "/opt/homebrew/opt/llvm@${{ matrix.llvm_version }}/bin" >> $GITHUB_PATH
          TMP_PATH=$(xcrun --show-sdk-path)/user/include
          echo "CPATH=$TMP_PATH" >> $GITHUB_ENV

      - name: CMake
        if: matrix.llvm_version < 18
        run: |
          cmake -B build -G Ninja -DC3_LLVM_VERSION=${{matrix.llvm_version}} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
          cmake --build build
      - name: CMake18
        if: matrix.llvm_version >= 18
        run: |
          cmake -B build -G Ninja -DC3_LLVM_VERSION=${{matrix.llvm_version}}.1 -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
          cmake --build build

      - name: Vendor-fetch
        run: |
          ./build/c3c vendor-fetch raylib55

      - name: Compile and run some examples
        run: |
          cd resources
          ../build/c3c compile-run examples/hello_world_many.c3
          ../build/c3c compile-run examples/time.c3
          ../build/c3c compile-run examples/fannkuch-redux.c3
          ../build/c3c compile-run examples/contextfree/boolerr.c3
          ../build/c3c compile-run examples/process.c3
          ../build/c3c compile-run examples/load_world.c3
          ../build/c3c compile-run -O5 examples/load_world.c3
          ../build/c3c compile-run examples/args.c3 -- foo -bar "baz baz"

      - name: Compile and run dynlib-test
        run: |
          cd resources/examples/dynlib-test
          ../../../build/c3c -vv dynamic-lib add.c3
          ../../../build/c3c compile-run test.c3 -l ./add.dylib          

      - name: Compile run unit tests
        run: |
          cd test
          ../build/c3c compile-test unit -O1 -D SLOW_TESTS

      - name: Test WASM
        run: |
          cd resources/testfragments
          ../../build/c3c compile --target wasm32 -g0 --no-entry -Os wasm4.c3

      - name: Build testproject
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --trust=full

      - name: Build testproject direct linker
        run: |
          cd resources/testproject
          ../../build/c3c run -vvv --linker=builtin --trust=full

      - name: Build testproject lib
        run: |
          cd resources/testproject
          ../../build/c3c build hello_world_lib -vvv --trust=full

      - name: run compiler tests
        run: |
          cd test
          ../build/c3c compile -O1 src/test_suite_runner.c3
          ./test_suite_runner ../build/c3c test_suite/

      - name: run build test suite runner
        run: |
          cd test
          ../build/c3c compile -O1 src/test_suite_runner.c3

      - name: bundle_output
        if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_MAC
        run: |
          mkdir macos
          cp -r lib macos
          cp msvc_build_libraries.py macos
          cp README.md macos
          cp releasenotes.md macos          
          cp build/c3c macos
          zip -r c3-macos-${{matrix.build_type}}.zip macos

      - name: upload artifacts
        if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_MAC
        uses: actions/upload-artifact@v4
        with:
          name: c3-macos-${{matrix.build_type}}
          path: c3-macos-${{matrix.build_type}}.zip

  build-nix:
    runs-on: ubuntu-22.04
    strategy:
      # Don't abort runners if a single one fails
      fail-fast: false
      matrix:
        build_type: [ Release, Debug ]
        nixpkgs: [ Lock, Latest ]
    steps:
    - uses: actions/checkout@v4

    - name: Install Nix
      uses: cachix/install-nix-action@v30
      with: 
        github_access_token: ${{ secrets.GITHUB_TOKEN }}

    - name: Update flake (if necessary)
      run: |
        if [[ matrix.nixpkgs == "Latest" ]]; then 
          nix flake update
        fi
        nix flake info

    - name: Build and check 
      run: |
        if [[ ${{ matrix.build_type }} = "Debug" ]]; then 
          nix build -L ".#c3c-debug-checks" 
        else 
          nix build -L ".#c3c-checks"
        fi

  build-openbsd:
    runs-on: ubuntu-latest
    strategy:
      # Don't abort runners if a single one fails
      fail-fast: false
      matrix:
        build_type: [Release, Debug]

    steps:
      - uses: actions/checkout@v4
      - name: OpenBSD VM
        uses: vmactions/openbsd-vm@main
        with:
          prepare: |
            pkg_add cmake llvm-19.1.7p3 ninja

          run: |
            echo "CMake"
            cmake -B build \
              -G Ninja \
              -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
              -DLLVM_ENABLE_LIBXML2=OFF \
              -DC3_LLVM_VERSION=${LLVM_RELEASE_VERSION_OPENBSD}
            cmake --build build
            echo "Compile and run some examples"
            cd resources
            ../build/c3c compile examples/base64.c3
            ../build/c3c compile examples/binarydigits.c3
            ../build/c3c compile examples/brainfk.c3
            ../build/c3c compile examples/factorial_macro.c3
            ../build/c3c compile examples/fasta.c3
            ../build/c3c compile examples/gameoflife.c3
            ../build/c3c compile examples/hash.c3
            ../build/c3c compile-only examples/levenshtein.c3
            ../build/c3c compile examples/load_world.c3
            ../build/c3c compile-only examples/map.c3
            ../build/c3c compile examples/mandelbrot.c3
            ../build/c3c compile examples/plus_minus.c3
            ../build/c3c compile examples/nbodies.c3
            ../build/c3c compile examples/spectralnorm.c3
            ../build/c3c compile examples/swap.c3
            ../build/c3c compile examples/contextfree/boolerr.c3
            ../build/c3c compile examples/contextfree/dynscope.c3
            ../build/c3c compile examples/contextfree/guess_number.c3
            ../build/c3c compile examples/contextfree/multi.c3
            ../build/c3c compile examples/contextfree/cleanup.c3
            ../build/c3c compile-run examples/hello_world_many.c3
            ../build/c3c compile-run examples/time.c3
            ../build/c3c compile-run examples/fannkuch-redux.c3
            ../build/c3c compile-run examples/contextfree/boolerr.c3
            ../build/c3c compile-run examples/load_world.c3
            ../build/c3c compile-run examples/process.c3
            ../build/c3c compile-run examples/ls.c3
            ../build/c3c compile-run examples/args.c3 -- foo -bar "baz baz"
            cd ..
            echo "Compile and run dynlib-test"
            cd resources/examples/dynlib-test
            ../../../build/c3c -vv dynamic-lib add.c3
            mv add.so libadd.so
            cc test.c -L. -ladd -Wl,-rpath=.         
            ./a.out
            ../../../build/c3c compile-run test.c3 -L . -l add -z -Wl,-rpath=.
            cd ../../../
            echo "Compile and run staticlib-test"
            cd resources/examples/staticlib-test
            ../../../build/c3c -vv static-lib add.c3
            mv add.a libadd.a
            cc test.c -L. -ladd         
            ./a.out
            ../../../build/c3c compile-run test.c3 -L . -l add           
            cd ../../../
            echo "Compile run unit tests"
            cd test
            ../build/c3c --max-mem 128 compile-test unit -D SLOW_TESTS
            cd ..
            echo "Build testproject"
            cd resources/testproject
            ../../build/c3c run -vvv --trust=full
            cd ../../
            echo "Test WASM"
            cd resources/testfragments
            ../../build/c3c compile --target wasm32 -g0 --no-entry -Os wasm4.c3
            cd ../../
            echo "Build testproject direct linker"
            cd resources/testproject
            ../../build/c3c run -vvv --linker=builtin --trust=full
            cd ../../
            echo "Init a library & a project"
            ./build/c3c init-lib mylib
            ls mylib.c3l
            ./build/c3c init myproject
            ls myproject
            echo "run compiler tests"
            cd test
            ../build/c3c --max-mem 128 compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c  test_suite/
            cd ..

      - name: bundle_output
        run: |
          mkdir c3
          cp -r lib c3
          cp msvc_build_libraries.py c3
          cp build/c3c c3
          cp README.md c3
          cp releasenotes.md c3
          tar czf c3-openbsd-${{matrix.build_type}}.tar.gz c3

      - name: upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: c3-openbsd-${{matrix.build_type}}
          path: c3-openbsd-${{matrix.build_type}}.tar.gz

  release:
    runs-on: ubuntu-22.04
    needs: [build-msvc, build-linux, build-mac, build-linux-ubuntu22]
    if: github.ref == 'refs/heads/master'
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
      - run: cp -r lib c3-windows-Release
      - run: cp -r lib c3-windows-Debug
      - run: cp msvc_build_libraries.py c3-windows-Release
      - run: cp msvc_build_libraries.py c3-windows-Debug
      - run: cp README.md c3-windows-Release
      - run: cp README.md c3-windows-Debug
      - run: cp releasenotes.md c3-windows-Release
      - run: cp releasenotes.md c3-windows-Debug
      - run: zip -r c3-windows.zip c3-windows-Release
      - run: zip -r c3-windows-debug.zip c3-windows-Debug
      - run: mv c3-linux-Release/c3-linux-Release.tar.gz c3-linux-Release/c3-linux.tar.gz
      - run: mv c3-linux-Debug/c3-linux-Debug.tar.gz c3-linux-Debug/c3-linux-debug.tar.gz
      - run: mv c3-openbsd-Release/c3-openbsd-Release.tar.gz c3-openbsd-Release/c3-openbsd.tar.gz
      - run: mv c3-openbsd-Debug/c3-openbsd-Debug.tar.gz c3-openbsd-Debug/c3-openbsd-debug.tar.gz
      - run: mv c3-ubuntu-22-Release/c3-ubuntu-22-Release.tar.gz c3-ubuntu-22-Release/c3-ubuntu-22.tar.gz
      - run: mv c3-ubuntu-22-Debug/c3-ubuntu-22-Debug.tar.gz c3-ubuntu-22-Debug/c3-ubuntu-22-debug.tar.gz
      - run: mv c3-macos-Release/c3-macos-Release.zip c3-macos-Release/c3-macos.zip
      - run: mv c3-macos-Debug/c3-macos-Debug.zip c3-macos-Debug/c3-macos-debug.zip
      - run: gh release delete latest-prerelease --cleanup-tag -y || true
      - run: echo "RELEASE_NAME=latest-prerelease-$(date +'%Y%m%d-%H%M')" >> $GITHUB_ENV

      - id: create_release
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: latest-prerelease
          name: ${{ env.RELEASE_NAME }}
          draft: false
          prerelease: true
          files: |
            c3-windows.zip
            c3-windows-debug.zip
            c3-linux-Release/c3-linux.tar.gz
            c3-linux-Debug/c3-linux-debug.tar.gz
            c3-openbsd-Release/c3-openbsd.tar.gz
            c3-openbsd-Debug/c3-openbsd-debug.tar.gz
            c3-ubuntu-22-Release/c3-ubuntu-22.tar.gz
            c3-ubuntu-22-Debug/c3-ubuntu-22-debug.tar.gz
            c3-macos-Release/c3-macos.zip
            c3-macos-Debug/c3-macos-debug.zip
