name: CI
#concurrency:
#  group: ${{ github.ref }}
#  cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
on:
  # # Triggers the workflow on push but only for the master branch
  push:
    branches: [master, develop]
    paths-ignore:
      - "**.md"
      - "version.properties"

  # Note: This is different from "pull_request". Need to specify ref when doing checkouts.
  pull_request_target:
    branches: [master, develop]
    paths-ignore:
      - "**.md"
      #- "**.yml"

  workflow_dispatch:

jobs:
  check:
    strategy:
      fail-fast: false
      matrix:
        include:
          - board: rak11200
          - board: tlora-v2-1-1_6
          - board: tbeam
          - board: heltec-v2_1
          - board: meshtastic-diy-v1
          - board: rak4631
          - board: t-echo
          - board: station-g2
          - board: m5stack-coreink
          - board: tbeam-s3-core
          - board: tlora-t3s3-v1
          - board: t-watch-s3
          - board: t-deck
          #- board: rak11310

    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build base
        id: base
        uses: ./.github/actions/setup-base

      - name: Trunk Check
        if: ${{ github.event_name != 'workflow_dispatch' }}
        uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b

      - name: Check ${{ matrix.board }}
        run: bin/check-all.sh ${{ matrix.board }}

  build-esp32:
    strategy:
      fail-fast: false
      matrix:
        include:
          - board: rak11200
          - board: tlora-v2
          - board: tlora-v1
          - board: tlora_v1_3
          - board: tlora-v2-1-1_6
          - board: tlora-v2-1-1_6-tcxo
          - board: tlora-v2-1-1_8
          - board: tbeam
          - board: heltec-v2_0
          - board: heltec-v2_1
          - board: tbeam0_7
          - board: meshtastic-diy-v1
          - board: hydra
          - board: meshtastic-dr-dev
          - board: nano-g1
          - board: station-g1
          - board: m5stack-core
          - board: m5stack-coreink
          - board: nano-g1-explorer
          - board: chatter2
    uses: ./.github/workflows/build_esp32.yml
    with:
      board: ${{ matrix.board }}

  build-esp32-s3:
    strategy:
      fail-fast: false
      matrix:
        include:
          - board: heltec-v3
          - board: heltec-wsl-v3
          - board: heltec-wireless-tracker
          - board: heltec-wireless-tracker-V1-0
          - board: heltec-wireless-paper-v1_0
          - board: heltec-wireless-paper #v1.1
          - board: tbeam-s3-core
          - board: tlora-t3s3-v1
          - board: t-watch-s3
          - board: t-deck
          - board: picomputer-s3
          - board: station-g2
          - board: unphone
    uses: ./.github/workflows/build_esp32_s3.yml
    with:
      board: ${{ matrix.board }}

  build-esp32-c3:
    strategy:
      fail-fast: false
      matrix:
        include:
          - board: heltec-ht62-esp32c3-sx1262
    uses: ./.github/workflows/build_esp32_c3.yml
    with:
      board: ${{ matrix.board }}

  build-nrf52:
    strategy:
      fail-fast: false
      matrix:
        include:
          - board: rak4631
          - board: rak4631_eink
          - board: monteops_hw1
          - board: t-echo
          - board: canaryone
          - board: pca10059_diy_eink
          - board: feather_diy
          - board: nano-g2-ultra
    uses: ./.github/workflows/build_nrf52.yml
    with:
      board: ${{ matrix.board }}

  build-rpi2040:
    strategy:
      fail-fast: false
      matrix:
        include:
          - board: pico
          - board: picow
          - board: rak11310
          - board: senselora_rp2040
          - board: rp2040-lora
    uses: ./.github/workflows/build_rpi2040.yml
    with:
      board: ${{ matrix.board }}

  build-raspbian:
    strategy:
      fail-fast: false
      max-parallel: 1
    uses: ./.github/workflows/build_raspbian.yml

  package-raspbian:
    uses: ./.github/workflows/package_raspbian.yml

  build-native:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build base
        id: base
        uses: ./.github/actions/setup-base

      # We now run integration test before other build steps (to quickly see runtime failures)
      #- name: Build for native
      #  run: platformio run -e native
      #- name: Integration test
      # run: |
      #.pio/build/native/program
      #& sleep 20 # 5 seconds was not enough
      #echo "Simulator started, launching python test..."
      #python3 -c 'from meshtastic.test import testSimulator; testSimulator()'

      - name: Build Native
        run: bin/build-native.sh

      - name: Get release version string
        run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
        id: version

      - name: Store binaries as an artifact
        uses: actions/upload-artifact@v3
        with:
          name: firmware-native-${{ steps.version.outputs.version }}.zip
          path: |
            release/device-*.sh
            release/device-*.bat

      - name: Docker login
        if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
        uses: docker/login-action@v2
        with:
          username: meshtastic
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Docker setup
        if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
        uses: docker/setup-buildx-action@v2

      - name: Docker build and push tagged versions
        if: ${{ github.event_name == 'workflow_dispatch' }}
        uses: docker/build-push-action@v3
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}

      - name: Docker build and push
        if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
        uses: docker/build-push-action@v3
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: meshtastic/device-simulator:latest

  after-checks:
    runs-on: ubuntu-latest
    needs: [check]
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: ${{github.event.pull_request.head.ref}}
          repository: ${{github.event.pull_request.head.repo.full_name}}

  gather-artifacts:
    permissions:
      contents: write
      pull-requests: write
    runs-on: ubuntu-latest
    needs:
      [
        build-esp32,
        build-esp32-s3,
        build-esp32-c3,
        build-nrf52,
        build-raspbian,
        build-native,
        build-rpi2040,
        package-raspbian,
      ]
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: ${{github.event.pull_request.head.ref}}
          repository: ${{github.event.pull_request.head.repo.full_name}}

      - uses: actions/download-artifact@v3
        with:
          path: ./

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

      - name: Get release version string
        run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
        id: version

      - name: Move files up
        run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./*esp32c3*/bleota-c3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase_v2.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat ./firmware-raspbian-*/release/meshtasticd_linux_aarch64 ./firmware-raspbian-*/bin/config-dist.yaml

      - name: Repackage in single firmware zip
        uses: actions/upload-artifact@v3
        with:
          name: firmware-${{ steps.version.outputs.version }}
          path: |
            ./*.bin
            ./*.uf2
            ./firmware-*-ota.zip
            ./device-*.sh
            ./device-*.bat
            ./meshtasticd_linux_arm64
            ./config-dist.yaml
          retention-days: 90

      - uses: actions/download-artifact@v3
        with:
          name: firmware-${{ steps.version.outputs.version }}
          path: ./output

      # For diagnostics
      - name: Show artifacts
        run: ls -lR

      - name: Device scripts permissions
        run: |
          chmod +x ./output/device-install.sh
          chmod +x ./output/device-update.sh

      - name: Zip firmware
        run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output

      - name: Repackage in single elfs zip
        uses: actions/upload-artifact@v3
        with:
          name: debug-elfs-${{ steps.version.outputs.version }}.zip
          path: ./*.elf
          retention-days: 30

      - name: Create request artifacts
        continue-on-error: true # FIXME: Why are we getting 502, but things still work?
        if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
        uses: gavv/pull-request-artifacts@v2.1.0
        with:
          commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          artifacts-token: ${{ secrets.ARTIFACTS_TOKEN }}
          artifacts-repo: meshtastic/artifacts
          artifacts-branch: device
          artifacts: ./firmware-${{ steps.version.outputs.version }}.zip

  release-artifacts:
    runs-on: ubuntu-latest
    if: ${{ github.event_name == 'workflow_dispatch' }}
    needs: [gather-artifacts, after-checks]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: 3.x

      - name: Get release version string
        run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
        id: version

      - uses: actions/download-artifact@v3
        with:
          name: firmware-${{ steps.version.outputs.version }}
          path: ./output

      - uses: actions/download-artifact@v3
        with:
          name: artifact-deb

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

      - name: Device scripts permissions
        run: |
          chmod +x ./output/device-install.sh
          chmod +x ./output/device-update.sh

      - name: Zip firmware
        run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output

      - uses: actions/download-artifact@v3
        with:
          name: debug-elfs-${{ steps.version.outputs.version }}.zip
          path: ./elfs

      - name: Zip Elfs
        run: zip -j -9 -r ./debug-elfs-${{ steps.version.outputs.version }}.zip ./elfs

      # For diagnostics
      - name: Show artifacts
        run: ls -lR

      - name: Create release
        uses: actions/create-release@v1
        id: create_release
        with:
          draft: true
          prerelease: true
          release_name: Meshtastic Firmware ${{ steps.version.outputs.version }} Alpha
          tag_name: v${{ steps.version.outputs.version }}
          body: |
            Autogenerated by github action, developer should edit as required before publishing...
        env:
          GITHUB_TOKEN: ${{ github.token }}

      - name: Add bins to release
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ github.token }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./firmware-${{ steps.version.outputs.version }}.zip
          asset_name: firmware-${{ steps.version.outputs.version }}.zip
          asset_content_type: application/zip

      - name: Add debug elfs to release
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ github.token }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./debug-elfs-${{ steps.version.outputs.version }}.zip
          asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
          asset_content_type: application/zip

      - name: Add raspbian .deb
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ github.token }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
          asset_name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
          asset_content_type: application/vnd.debian.binary-package

      - name: Bump version.properties
        run: >-
          bin/bump_version.py

      - name: Create version.properties pull request
        uses: peter-evans/create-pull-request@v3
        with:
          add-paths: |
            version.properties
