#
#  Copyright (c) 2021, The OpenThread Authors.
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#  3. Neither the name of the copyright holder nor the
#     names of its contributors may be used to endorse or promote products
#     derived from this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#  POSSIBILITY OF SUCH DAMAGE.
#

name: Border Router

on:
  push:
    branches-ignore:
      - 'dependabot/**'
  pull_request:
    branches:
      - 'main'

jobs:

  cancel-previous-runs:
    runs-on: ubuntu-20.04
    steps:
    - uses: rokroskar/workflow-run-cleanup-action@master
      env:
        GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
      if: "github.ref != 'refs/heads/main'"

  border-router:
    runs-on: ubuntu-20.04

    strategy:
      fail-fast: false
      matrix:
        include:
          - name: "Border Router (mDNSResponder)"
            otbr_options: "-DOT_TREL=OFF -DOT_MLR=ON -DOTBR_COVERAGE=ON -DOT_SRP_SERVER=ON -DOT_ECDSA=ON -DOT_SERVICE=ON -DOTBR_DUA_ROUTING=ON -DOT_DUA=ON -DOTBR_BORDER_ROUTING_NAT64=ON"
            border_routing: 1
            otbr_mdns: "mDNSResponder"
            cert_scripts: ./tests/scripts/thread-cert/border_router/*.py
            packet_verification: 1
          - name: "Border Router (Avahi)"
            otbr_options: "-DOT_TREL=OFF -DOT_MLR=ON -DOTBR_COVERAGE=ON -DOT_SRP_SERVER=ON -DOT_ECDSA=ON -DOT_SERVICE=ON -DOTBR_DUA_ROUTING=ON -DOT_DUA=ON -DOTBR_BORDER_ROUTING_NAT64=ON"
            border_routing: 1
            otbr_mdns: "avahi"
            cert_scripts: ./tests/scripts/thread-cert/border_router/*.py
            packet_verification: 1
          - name: "Border Router TREL (mDNSResponder)"
            otbr_options: "-DOT_TREL=ON -DOT_MLR=ON -DOTBR_COVERAGE=ON -DOT_SRP_SERVER=ON -DOT_ECDSA=ON -DOT_SERVICE=ON -DOTBR_DUA_ROUTING=ON -DOT_DUA=ON -DOTBR_BORDER_ROUTING_NAT64=ON"
            border_routing: 1
            otbr_mdns: "mDNSResponder"
            cert_scripts: ./tests/scripts/thread-cert/border_router/*.py
            packet_verification: 2
          - name: "Border Router TREL (Avahi)"
            otbr_options: "-DOT_TREL=ON -DOT_MLR=ON -DOTBR_COVERAGE=ON -DOT_SRP_SERVER=ON -DOT_ECDSA=ON -DOT_SERVICE=ON -DOTBR_DUA_ROUTING=ON -DOT_DUA=ON -DOTBR_BORDER_ROUTING_NAT64=ON"
            border_routing: 1
            otbr_mdns: "avahi"
            cert_scripts: ./tests/scripts/thread-cert/border_router/*.py
            packet_verification: 2
          - name: "Border Router MATN (mDNSResponder)"
            otbr_options: "-DOT_TREL=OFF -DOT_MLR=ON -DOTBR_COVERAGE=ON -DOT_SRP_SERVER=ON -DOT_ECDSA=ON -DOT_SERVICE=ON -DOTBR_DUA_ROUTING=ON -DOT_DUA=ON -DOTBR_BORDER_ROUTING_NAT64=ON"
            border_routing: 1
            otbr_mdns: "mDNSResponder"
            cert_scripts: ./tests/scripts/thread-cert/border_router/MATN/*.py
            packet_verification: 1
          - name: "Border Router NAT64 (mDNSResponder)"
            otbr_options: "-DOT_TREL=OFF -DOT_MLR=ON -DOTBR_COVERAGE=ON -DOT_SRP_SERVER=ON -DOT_ECDSA=ON -DOT_SERVICE=ON -DOTBR_DUA_ROUTING=ON -DOT_DUA=ON -DOTBR_BORDER_ROUTING_NAT64=ON"
            border_routing: 1
            otbr_mdns: "mDNSResponder"
            cert_scripts: ./tests/scripts/thread-cert/border_router/nat64/*.py
            packet_verification: 1
          - name: "Backbone Router"
            otbr_options: "-DOT_TREL=OFF -DOT_DUA=ON -DOT_MLR=ON -DOTBR_COVERAGE=ON -DOT_SRP_SERVER=ON -DOT_ECDSA=ON -DOT_SERVICE=ON -DOTBR_DUA_ROUTING=ON"
            border_routing: 0
            otbr_mdns: "mDNSResponder"
            cert_scripts: ./tests/scripts/thread-cert/backbone/*.py
            packet_verification: 1


    name: ${{ matrix.name }}
    env:
      PACKET_VERIFICATION: ${{ matrix.packet_verification }}
      THREAD_VERSION: 1.3
      VIRTUAL_TIME: 0
      PYTHONUNBUFFERED: 1
      REFERENCE_DEVICE: 1
      OTBR_COVERAGE: 1
      READLINE: readline
      INTER_OP: 0
      INTER_OP_BBR: 0
      BORDER_ROUTING: ${{ matrix.border_routing }}
      MAX_JOBS: 3
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: true
    - name: Get Border Router Test ID
      id: unique_action_id
      run: |
        echo ::set-output name=id::"${GITHUB_WORKFLOW}-${GITHUB_JOB}-${GITHUB_RUN_ID}-${{matrix.name}}"
    - name: Check cached result
      id: check_cache_result
      uses: actions/cache@v2
      with:
        path: |
          _test_complete_
        key: "_test_complete_${{ steps.unique_action_id.outputs.id }}"
    - name: Build OTBR Docker Image
      if: ${{ success() && steps.check_cache_result.outputs.cache-hit != 'true' }}
      run: |
        # We need the `-DOT_SRP_SERVER=ON` option because the `bbr_5_11_01.py` script is referring SRP server.
        # This should be fixed by enhancing the test script to handle SRP server situations properly.
        otbr_options="${{ matrix.otbr_options }}"
        otbr_image_name="otbr-ot12-backbone-ci"
        docker build -t "${otbr_image_name}" -f etc/docker/Dockerfile . \
          --build-arg BORDER_ROUTING=${{ matrix.border_routing }} \
          --build-arg INFRA_IF_NAME=eth0 \
          --build-arg BACKBONE_ROUTER=1 \
          --build-arg REFERENCE_DEVICE=1 \
          --build-arg OT_BACKBONE_CI=1 \
          --build-arg NAT64=0 \
          --build-arg MDNS="${{ matrix.otbr_mdns }}" \
          --build-arg OTBR_OPTIONS="${otbr_options} -DCMAKE_CXX_FLAGS='-DOPENTHREAD_CONFIG_DNSSD_SERVER_BIND_UNSPECIFIED_NETIF=1'"
    - name: Bootstrap OpenThread Test
      if: ${{ success() && steps.check_cache_result.outputs.cache-hit != 'true' }}
      run: |
        sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
        sudo apt-get --no-install-recommends install -y python3-setuptools python3-wheel ninja-build socat nodejs npm
        python3 -m pip install -r third_party/openthread/repo/tests/scripts/thread-cert/requirements.txt
    - name: Build OpenThread
      if: ${{ success() && steps.check_cache_result.outputs.cache-hit != 'true' }}
      run: |
        (cd third_party/openthread/repo && ./script/test build)
    - name: Get Thread-Wireshark
      if: ${{ success() && steps.check_cache_result.outputs.cache-hit != 'true' }}
      run: |
        (cd third_party/openthread/repo && ./script/test get_thread_wireshark)
    - name: Run Test
      if: ${{ success() && steps.check_cache_result.outputs.cache-hit != 'true' }}
      run: |
        export CI_ENV="$(bash <(curl -s https://codecov.io/env)) -e GITHUB_ACTIONS -e OTBR_COVERAGE"
        echo "CI_ENV=${CI_ENV}"
        (cd third_party/openthread/repo && sudo -E ./script/test cert_suite ${{ matrix.cert_scripts }} || (sudo chmod a+r *.log *.json *.pcap && false))
    - uses: actions/upload-artifact@v2
      if: ${{ failure() && steps.check_cache_result.outputs.cache-hit != 'true' }}
      with:
        name: thread-1-3-backbone-results
        path: |
          third_party/openthread/repo/*.pcap
          third_party/openthread/repo/*.json
          third_party/openthread/repo/*.log
    - name: Codecov
      if: ${{ success() && steps.check_cache_result.outputs.cache-hit != 'true' }}
      uses: codecov/codecov-action@v2
    - name: Cache test result
      if: ${{ success() && steps.check_cache_result.outputs.cache-hit != 'true' }}
      run: |
        mkdir _test_complete_
