name: "CI"

on: [push]
jobs:
  Ubuntu:
    runs-on: ubuntu-latest
    outputs:
      cache_misses: ${{ env.cache_misses }}
    steps:
      - uses: actions/checkout@v4
      - name: Install required packages
        run: |
          sudo apt-get update
          sudo apt-get -y install apt-utils
          sudo apt-get -y install git gcc g++ cmake python3 make ninja-build
          sudo apt-get -y install tcpdump libgsl-dev libxml2-dev
          sudo apt-get -y install curl unzip tar
          sudo apt-get -y install ccache
      - name: Get timestamp
        id: time
        run: python3 -c "from datetime import datetime; print('time='+datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))" >> $GITHUB_ENV
      - name: Restore ccache
        id: ccache
        uses: actions/cache@v4
        with:
          path: .ccache
          key: ubuntu-ci-${{env.time}}
          restore-keys: ubuntu-ci-
      - name: Setup ccache
        run: |
          ccache --set-config=cache_dir="$GITHUB_WORKSPACE/.ccache"
          ccache --set-config=max_size=400M
          ccache --set-config=compression=true
          ccache -z
      - name: Configure CMake
        run: |
          ./ns3 configure -d release --enable-asserts --enable-examples --enable-tests --disable-werror -G"Ninja"
      - name: Build ns-3
        run: |
          ./ns3 build
      - name: Print ccache statistics
        id: ccache_results
        run: |
          ccache -s
          python3 -c "import re, subprocess;print('cache_misses=%d' % int(re.findall('cache_miss(.*)', subprocess.check_output(['ccache', '--print-stats']).decode())[0]))" >> $GITHUB_ENV
      - name: Run tests and examples
        if: env.cache_misses != '0'
        run: python3 test.py --no-build --verbose-failed

  Codecov:
    runs-on: ubuntu-latest
    needs: Ubuntu
    if: needs.Ubuntu.outputs.cache_misses != '0'
    steps:
      - uses: actions/checkout@v4
      - name: Install required packages
        run: |
          sudo apt-get update
          sudo apt-get -y install apt-utils
          sudo apt-get -y install git gcc g++ cmake python3 make ninja-build
          sudo apt-get -y install tcpdump libgsl-dev libxml2-dev
          sudo apt-get -y install curl unzip tar
          sudo apt-get -y install ccache
          sudo apt-get -y install lcov
      - name: Get timestamp
        id: time
        run: python3 -c "from datetime import datetime; print('time='+datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))" >> $GITHUB_ENV
      - name: Restore ccache
        id: ccache
        uses: actions/cache@v4
        with:
          path: .ccache
          key: ubuntu-coverage-${{env.time}}
          restore-keys: ubuntu-coverage-
      - name: Setup ccache
        run: |
          ccache --set-config=cache_dir="$GITHUB_WORKSPACE/.ccache"
          ccache --set-config=max_size=400M
          ccache --set-config=compression=true
          ccache -z
      - name: Configure CMake
        run: |
          ./ns3 configure --enable-asserts --enable-examples --enable-tests --disable-werror --enable-gcov -G"Ninja"
      - name: Build ns-3
        run: |
          ./ns3 build
      - name: Print ccache statistics
        id: ccache_results
        run: |
          ccache -s
          python3 -c "import re, subprocess;print('cache_misses=%d' % int(re.findall('cache_miss(.*)', subprocess.check_output(['ccache', '--print-stats']).decode())[0]))" >> $GITHUB_ENV
      - name: Generate coverage data and submit to codecov.io
        if: env.cache_misses != '0'
        run: |
          ./ns3 build coverage_gcc
          cd ./build/coverage
          bash <(curl -s https://codecov.io/bash) -f ns3.info || echo "Codecov did not collect coverage reports"
        env:
          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
  Windows_MinGW:
    runs-on: windows-latest
    defaults:
      run:
        shell: msys2 {0}
    steps:
      - uses: actions/checkout@v4
      - uses: msys2/setup-msys2@v2
      - name: Install required msys2/mingw64 packages
        run: |
          pacman -S --noconfirm \
          unzip \
          tar \
          mingw-w64-x86_64-curl \
          mingw-w64-x86_64-binutils \
          mingw-w64-x86_64-cmake \
          mingw-w64-x86_64-gcc \
          mingw-w64-x86_64-ninja \
          mingw-w64-x86_64-python \
          mingw-w64-x86_64-ccache \
          mingw-w64-x86_64-gsl \
          mingw-w64-x86_64-libxml2 \
          mingw-w64-x86_64-lld \
          mingw-w64-x86_64-sed
          pacman --noconfirm -Scc
      - name: Get timestamp
        id: time
        run: python3 -c "from datetime import datetime; print('time='+datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))" >> $GITHUB_ENV
      - name: Restore ccache
        id: ccache
        uses: actions/cache@v4
        with:
          path: .ccache
          key: msys2-${{env.time}}
          restore-keys: msys2-
      - name: Setup ccache
        run: |
          ccache --set-config=cache_dir="$GITHUB_WORKSPACE/.ccache"
          ccache --set-config=max_size=400M
          ccache --set-config=compression=true
          ccache -z
      - name: Configure CMake
        run: |
          python3 ns3 configure -d release --enable-asserts --enable-examples --enable-tests --disable-werror -G"Ninja"
      - name: Build ns-3
        run: |
          python3 ns3 build
      - name: Print ccache statistics
        id: ccache_results
        run: |
          ccache -s
          python3 -c "import re, subprocess;print('cache_misses=%d' % int(re.findall('cache_miss(.*)', subprocess.check_output(['ccache', '--print-stats']).decode())[0]))" >> $GITHUB_ENV
      - name: Run tests and examples
        if: env.cache_misses != '0'
        run: python3 test.py --no-build --verbose-failed

  Mac_OS_X:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ macos-latest, macos-14 ]
    steps:
      - uses: actions/checkout@v4
      - name: Install required packages
        run: |
          brew uninstall cmake ninja
          brew install ninja cmake ccache libxml2 gsl open-mpi #qt5
      - name: Get timestamp
        id: time
        run: python3 -c "from datetime import datetime; print('time='+datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))" >> $GITHUB_ENV
      - name: Restore ccache
        id: ccache
        uses: actions/cache@v4
        with:
          path: .ccache
          key: osx_brew-ci-${{env.time}}
          restore-keys: osx_brew-ci-
      - name: Setup ccache
        run: |
          export PATH=/usr/local/bin:$PATH #:/usr/local/opt/qt/bin
          ccache --set-config=cache_dir="$GITHUB_WORKSPACE/.ccache"
          ccache --set-config=max_size=400M
          ccache --set-config=compression=true
          ccache -z
      - name: Configure CMake
        run: |
          export PATH=/usr/local/bin:$PATH #:/usr/local/opt/qt/bin
          ./ns3 configure -d release --enable-asserts --enable-examples --enable-tests --disable-werror -G"Ninja"
      - name: Build ns-3
        run: |
          export PATH="$PATH" #:/usr/local/opt/qt/bin
          ./ns3 build
      - name: Print ccache statistics
        id: ccache_results
        run: |
          ccache -s
          python3 -c "import re, subprocess;print('cache_misses=%d' % int(re.findall('cache_miss(.*)', subprocess.check_output(['ccache', '--print-stats']).decode())[0]))" >> $GITHUB_ENV
      - name: Run tests and examples
        if: env.cache_misses != '0'
        run: ./test.py --no-build --verbose-failed
  Windows_Visual_Studio:
    runs-on: windows-latest
    defaults:
      run:
        shell: cmd
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
      - name: Configure CMake
        run: |
          %comspec% /k ""C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat""
          python ns3 configure --enable-tests --enable-examples --enable-asserts -d release -- -G"Visual Studio 17 2022" -A x64 -T ClangCL
      - name: Build ns-3
        run: |
          %comspec% /k ""C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat""
          python ns3 build
      - name: Run tests and examples
        run: |
          set PATH=%CD%\build;%PATH%
          python .\test.py --no-build --verbose-failed
