name: Build_Multiplatform
on: [push]

jobs:
  BUILD_AMD64:
    name: Build codec2 for x86/x64 devices
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-18.04, ubuntu-20.04, ubuntu-22.04, macos-11, macos-12]
        platform: [{name: "native"}, {name: "Windows", file: "dll"}]
        architecture: [i686-w64-mingw32, x86_64-w64-mingw32]
        include:
          - os: ubuntu-18.04
            libcodec2_name: libcodec2.so.1.0
            libcodec2_os_name: libcodec2_ubuntu-1804
            libcodec2_filetype: so
            generator: Unix Makefiles
            shell: bash

          - os: ubuntu-20.04
            libcodec2_name: libcodec2.so.1.0
            libcodec2_os_name: libcodec2_ubuntu-2004
            libcodec2_filetype: so
            generator: Unix Makefiles
            shell: bash

          - os: ubuntu-22.04
            libcodec2_name: libcodec2.so.1.0
            libcodec2_os_name: libcodec2_ubuntu-2204
            libcodec2_filetype: so
            generator: Unix Makefiles
            shell: bash

          - os: macos-11
            libcodec2_name: libcodec2.1.0.dylib
            libcodec2_os_name: libcodec2_macos-11
            libcodec2_filetype: dylib
            generator: Unix Makefiles
            shell: bash

          - os: macos-12
            libcodec2_name: libcodec2.1.0.dylib
            libcodec2_os_name: libcodec2_macos-12
            libcodec2_filetype: dylib
            generator: Unix Makefiles
            shell: bash


    steps:
      - name: Build codec2 on ${{ matrix.os }} for ${{ matrix.platform.name }}
        if: ${{startsWith(matrix.platform.name, 'native') }}
        run: |
          git clone https://github.com/drowe67/codec2.git
          cd codec2
          mkdir build
          mkdir tempfiles
          cd build
          cmake ../
          make
          mv src/${{ matrix.libcodec2_name }} ../tempfiles/libcodec2_${{ matrix.os }}_${{ matrix.platform.name }}.${{ matrix.libcodec2_filetype }}

      - name: LIST ALL FILES ${{ github.workspace }}
        run: ls -R ${{ github.workspace }}

      - uses: actions/upload-artifact@v3
        if: ${{startsWith(matrix.platform.name, 'native') }}
        with:
          name: libcodec2_${{ matrix.os }}_${{ matrix.platform.name }}.${{ matrix.libcodec2_filetype }}
          # path: ${{ github.workspace }}/codec2/tempfiles/libcodec2_${{ matrix.os }}_${{ matrix.platform.name }}.${{ matrix.libcodec2_filetype }}
          path: ${{ github.workspace }}/codec2/tempfiles/


      - name: Build codec2 ${{ matrix.platform.name }} ${{ matrix.architecture }}
        if: ${{startsWith(matrix.os, 'ubuntu-20') && !startsWith(matrix.platform.name, 'native') }}
        run: |
          sudo apt install build-essential mingw-w64 g++-mingw-w64 make cmake
          git clone https://github.com/drowe67/codec2.git
          cd codec2
          mkdir tempfiles
          mkdir build_w32
          cd build_w32
          echo 'set(CMAKE_SYSTEM_NAME ${{ matrix.platform.name }})' > toolchain-ubuntu-mingw32.cmake
          echo 'set(CMAKE_C_COMPILER ${{ matrix.architecture }}-gcc)' >> toolchain-ubuntu-mingw32.cmake
          echo 'set(CMAKE_CXX_COMPILER ${{ matrix.architecture }}-g++)' >> toolchain-ubuntu-mingw32.cmake
          echo 'set(CMAKE_RC_COMPILER ${{ matrix.architecture }}-windres)' >> toolchain-ubuntu-mingw32.cmake
          echo 'set(CMAKE_FIND_ROOT_PATH /usr/${{ matrix.architecture }})' >> toolchain-ubuntu-mingw32.cmake
          echo 'set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)' >> toolchain-ubuntu-mingw32.cmake
          echo 'set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)' >> toolchain-ubuntu-mingw32.cmake
          echo 'set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)' >> toolchain-ubuntu-mingw32.cmake
          echo 'set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")' >> toolchain-ubuntu-mingw32.cmake
          cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain-ubuntu-mingw32.cmake ..
          make
          mv src/libcodec2.${{ matrix.platform.file }} ../tempfiles/libcodec2_${{ matrix.platform.name }}_${{ matrix.architecture }}.${{ matrix.platform.file }}

      - uses: actions/upload-artifact@v3
        if: ${{startsWith(matrix.os, 'ubuntu-20') && !startsWith(matrix.platform.name, 'native') }}
        with:
          name: libcodec2_${{ matrix.os }}_${{ matrix.platform.name }}_${{ matrix.architecture }}.${{ matrix.platform.file }}
          path: codec2/tempfiles/*




  BUILD_ARM:
    # The host should always be linux
    runs-on: ubuntu-latest
    name: Build codec2 for ARM devices

    # Run steps on a matrix of 2 arch/distro combinations
    strategy:
      matrix:
        include:
          - arch: armv7
            distro: bullseye
            libcodec2_os_name: libcodec2_bullseye_armv7.so
          - arch: armv7
            distro: ubuntu_latest
            libcodec2_os_name: libcodec2_ubuntu_latest_armv7.so

    steps:
      - uses: actions/checkout@v3
      - uses: uraimo/run-on-arch-action@v2
        name: Build artifact
        id: build
        with:
          arch: ${{ matrix.arch }}
          distro: ${{ matrix.distro }}

          # Not required, but speeds up builds
          githubToken: ${{ github.token }}

          # Create an artifacts directory
          setup: |
            mkdir -p "${PWD}/artifacts"

          # Mount the artifacts directory as /artifacts in the container
          dockerRunArgs: |
            --volume "${PWD}/artifacts:/artifacts"

          # Pass some environment variables to the container
          env: | # YAML, but pipe character is necessary
            artifact_name: ${{ matrix.libcodec2_os_name }}

          # The shell to run commands with in the container
          shell: /bin/sh

          # Install some dependencies in the container. This speeds up builds if
          # you are also using githubToken. Any dependencies installed here will
          # be part of the container image that gets cached, so subsequent
          # builds don't have to re-install them. The image layer is cached
          # publicly in your project's package repository, so it is vital that
          # no secrets are present in the container state or logs.
          install: |
            case "${{ matrix.distro }}" in
              ubuntu*|jessie|stretch|buster|bullseye)
                apt-get update -q -y
                apt-get install -q -y git build-essential cmake gcc g++
                cmake --version
                ;;
              fedora*)
                dnf -y update
                dnf -y install git which make cmake gcc-c++ gcc
                cmake --version
                ;;
              alpine*)
                apk update
                apk add git cmake gcc g++
                cmake --version
                ;;
            esac

          # Produce a binary artifact and place it in the mounted volume
          run: |

            git clone https://github.com/drowe67/codec2.git
            cd codec2
            git checkout master
            mkdir build
            cd build
            cmake ../
            make
            mv ./src/libcodec2.so.1.0 /artifacts/${artifact_name}

      - name: Show recursive PWD/artifacts
        # Items placed in /artifacts in the container will be in
        # ${PWD}/artifacts on the host.
        run: ls -al "${PWD}/artifacts"

      - uses: actions/upload-artifact@v3
        with:
          name: ${{ matrix.libcodec2_os_name }}
          #path: $GITHUB_WORKSPACE/codec2/artifacts/*
          path: artifacts/*

  build_i686_x64_release:
    needs: [BUILD_AMD64]
    name: Build FreeDATA packages
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-20.04, macos-11, windows-latest]
        include:
          - os: ubuntu-20.04
            zip_name: ubuntu_tnc
            generator: Unix Makefiles
            daemon_binary_name: freedata-daemon
            tnc_binary_name: freedata-tnc
            electron_parameters: "-p always"

          - os: macos-11
            zip_name: macos_tnc
            generator: Unix Makefiles
            daemon_binary_name: freedata-daemon
            tnc_binary_name: freedata-tnc
            electron_parameters: "-p always"

          - os: windows-latest
            zip_name: windows_tnc
            generator: Visual Studio 16 2019
            daemon_binary_name: freedata-daemon.exe
            tnc_binary_name: freedata-tnc.exe
            electron_parameters: "-p always --x64 --ia32"
    steps:
      - name: Checkout code for ${{ matrix.platform.name }}
        uses: actions/checkout@v3
        with:
          repository: DJ2LS/FreeDATA

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

      - name: Install Node.js, NPM and Yarn
        uses: actions/setup-node@v3
        with:
          node-version: 16

      - name: Create tnc/dist
        working-directory: tnc
        run: |
          mkdir -p dist

      - name: Create tnc/dist/tnc
        working-directory: tnc
        run: |
          mkdir -p dist/tnc

      ##- name: Download libcodec2 artifact TNC DIST
      ##  uses: actions/download-artifact@v3
      ##  with:
      ##    path: tnc/dist/codec2

      - name: create tnc/lib/codec2
        working-directory: tnc/lib/
        run: |
          mkdir codec2

      - name: Download libcodec2 artifact TNC LIB
        uses: actions/download-artifact@v3
        with:
          path: tnc/lib/codec2


      - name: Install Linux dependencies
        # if: matrix.os == 'ubuntu-20.04'
        if: ${{startsWith(matrix.os, 'ubuntu')}}
        run: |
          sudo apt install -y portaudio19-dev libhamlib-dev libhamlib-utils build-essential cmake python3-libhamlib2

      - name: Install MacOS pyAudio
        if: ${{startsWith(matrix.os, 'macos')}}
        run: |
          brew install portaudio
          python -m pip install --upgrade pip
          pip3 install pyaudio

      - name: Install Python dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt


      # - name: Install Pyaudio Windows
      #   if: ${{startsWith(matrix.os, 'windows')}}
      #   working-directory: tnc/lib/pyaudio/windows
      #   run: |
      #     pip install PyAudio-0.2.11-cp39-cp39-win_amd64.whl

      # - name: Display structure of downloaded files
      #   run: ls -R

      # - name: cleanup codec2
      #   working-directory: tnc/lib/
      #   run: |
      #     mkdir codec2
      #     cd codec2

      # - uses: actions/download-artifact@v3
      #   with:
      #     path: tnc/lib/codec2

      - name: Build binaries
        working-directory: tnc
        run: |
          # pyinstaller freedata.spec
          # python3 -m nuitka --enable-plugin=numpy --assume-yes-for-downloads --onefile daemon.py -o ${{ matrix.daemon_binary_name }}
          # python3 -m nuitka --enable-plugin=numpy --assume-yes-for-downloads --onefile main.py -o ${{ matrix.tnc_binary_name }}
          python3 -m nuitka --enable-plugin=numpy --assume-yes-for-downloads --standalone daemon.py
          python3 -m nuitka --enable-plugin=numpy --assume-yes-for-downloads --standalone main.py

      - name: Copy binaries - Linux and MacOS
        if: ${{!startsWith(matrix.os, 'windows')}}
        working-directory: tnc
        run: |
          cp -r -f daemon.dist/* dist/tnc
          cp -r -f main.dist/* dist/tnc

      - name: Copy binaries - Windows
        if: ${{startsWith(matrix.os, 'windows')}}
        working-directory: tnc
        # These are powershell aliases, not UNIX commands.
        run: |
          cp -r -Force daemon.dist/* dist/tnc
          cp -r -Force main.dist/* dist/tnc

      - name: Rename tnc binaries
        working-directory: tnc
        run: |
          mv dist/tnc/daemon* dist/tnc/${{ matrix.daemon_binary_name }}
          mv dist/tnc/main* dist/tnc/${{ matrix.tnc_binary_name }}

      - uses: actions/download-artifact@v3
        with:
           path: tnc/dist/tnc

      - name: LIST ALL FILES
        run: ls -R

      - name: Download Portaudio binaries
        working-directory: tnc
        run: |
          git clone https://github.com/spatialaudio/portaudio-binaries dist/tnc/_sounddevice_data/portaudio-binaries

      - name: LIST ALL FILES
        run: ls -R

      #- name: Compress TNC
      #  # if: ${{!startsWith(matrix.os, 'windows') }}
      #  shell: bash
      #  run: |
      #    cd ./tnc/dist
      #    zip -r ./${{ matrix.zip_name }}.zip *

      ##- name: Copy TNC to GUI
      ##  run: |
      ##    # cp -R ./tnc/dist/tnc ./gui/tnc
      ##    cp -R ./tnc/dist ./gui/tnc

      ##- name: LIST ALL FILES
      ##  run: ls -R

      ##- name: Compress TNC
      ##  uses: thedoctor0/zip-release@master
      ##  with:
      ##      type: 'zip'
      ##      filename: '${{ matrix.zip_name }}'
      ##      # directory: ./tnc/dist/tnc
      ##      directory: ./tnc/dist/tnc
      ##      path: .
      ##      # exclusions: '*.git* /*node_modules/* .editorconfig'

      ##- name: LIST ALL FILES
      ##  run: ls -R

      ##- name: Upload TNC artifacts
      ##  uses: actions/upload-artifact@v3
      ##  with:
      ##    name: ${{ matrix.zip_name }}.zip
      ##    # path: ./tnc/dist/tnc/${{ matrix.zip_name }}.zip
      ##    path: ./tnc/dist/${{ matrix.zip_name }}.zip


      ##- name: Release TNC
      ##  uses: softprops/action-gh-release@v1
      ##  if: startsWith(github.ref, 'refs/tags/v')
      ##  with:
      ##    files: ./tnc/dist/tnc/${{ matrix.zip_name }}.zip
      ##    #files: ./tnc/dist/${{ matrix.zip_name }}.zip

      - name: Build/release Electron app
        uses: samuelmeuli/action-electron-builder@v1
        with:
          package_root: "./gui/"
          github_token: ${{ secrets.github_token }}
          # If the commit is tagged with a version (e.g. "v1.0.0"),
          # release the app after building
          release: ${{ startsWith(github.ref, 'refs/tags/v') }}
          args: ${{ matrix.electron_parameters }}

      - name: Compress TNC
        uses: thedoctor0/zip-release@master
        with:
            type: 'zip'
            filename: '${{ matrix.zip_name }}.zip'
            # directory: ./tnc/dist/tnc
            directory: ./tnc/dist/tnc
            path: .
            # exclusions: '*.git* /*node_modules/* .editorconfig'

      - name: Release TNC
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/v')
        with:
          files: ./tnc/dist/tnc/${{ matrix.zip_name }}.zip
          #files: ./tnc/dist/${{ matrix.zip_name }}.zip

      - name: LIST ALL FILES
        run: ls -R

      #- name: Upload TNC artifacts
      #  uses: actions/upload-artifact@v3
      #  if: ${{!startsWith(github.ref, 'refs/tags/v')}}
      #  with:
      #    name: ${{ matrix.zip_name }}.zip
      #    # path: ./tnc/dist/tnc/${{ matrix.zip_name }}.zip
      #    path: ./tnc/dist/tnc/${{ matrix.zip_name }}.zip#

      #- name: Upload App bundle artifacts
      #  uses: actions/upload-artifact@v3
      #  if: ${{!startsWith(github.ref, 'refs/tags/v')}}
      #  with:
      #    name: app_bundle_${{ matrix.os }}.zip
      #     # path: ./tnc/dist/tnc/${{ matrix.zip_name }}.zip
      #    path: ./gui/dist/*
