###############################################################
# SPDX-License-Identifier: BSD-2-Clause-Patent
# SPDX-FileCopyrightText: 2019-2020 the prplMesh contributors (see AUTHORS.md)
# This code is subject to the terms of the BSD+Patent license.
# See LICENSE file for more details.
###############################################################

variables:
  PACKAGE_REGISTRY_BASE_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic"
  TURRIS_OMNIA_FULLIMAGE: "openwrt-mvebu-cortexa9-cznic_turris-omnia-sysupgrade.img.gz"
  TURRIS_OMNIA_RDKB_FULLIMAGE: "rdkb-generic-broadband-image_turris-omnia.rootfs.tar.gz"
  HAZE_FULLIMAGE: "openwrt-ipq807x-generic-prpl_haze-squashfs-sysupgrade.bin"
  FREEDOM_FULLIMAGE: "openwrt-ipq95xx-generic-prpl_freedom-squashfs-sysupgrade.bin"
  OSP_PACKAGE_ID: 13754300

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "parent_pipeline"'

stages:
  - build
  - test
  - certification-R1-haze
  - certification-R1-turris-omnia
  - certification-R4-freedom
  - certification-R4-haze
  - certification-R4-turris-omnia
  - upload
  - release

include:
  - local: "/ci/templates.yml"
  - local: "/ci/certification/templates.yml"

.rules-for-releases: &onrelease
  - if: '$CI_COMMIT_TAG =~ /\A\d+\.\d+\.\d+\z/'

build-for-rdkb-turris-omnia:
  extends: .build-for-rdkb
  variables:
    TARGET_DEVICE: "turris-omnia"
  retry: 2

build-for-turris-omnia:
  extends: .build-for-openwrt
  variables:
    TARGET_DEVICE: "turris-omnia"
  tags:
    - shell
    - docker-build
    - turris-build

build-for-haze:
  extends: .build-for-openwrt
  variables:
    TARGET_DEVICE: "haze"
  tags:
    - shell
    - docker-build
    - haze-build

build-for-freedom:
  extends: .build-for-openwrt
  variables:
    TARGET_DEVICE: "freedom"
  tags:
    - shell
    - docker-build
    - freedom-build

build-for-osp-ospv2:
  stage: build
  variables:
    POLLING_RATE: "120"
    TESTS_TO_RUN_R4_ESSENSIUM: ""
    DEVICE_UNDER_TEST_R4_ESSENSIUM: ""
  script:
    - echo "Triggering OSP runner to start external build"
    - |
      trigger_details=$(curl -X POST --retry 3 -s -f -F \
      token=${OSP_PIPELINE_TRIGGER_TOKEN_2} \
      -F ref="mainline-23.05-v4" \
      -F variables[PRPLMESH_REVISION]="$CI_COMMIT_SHA" \
      -F variables[PRPLMESH_COMMIT_REF_NAME]="$CI_COMMIT_REF_NAME" \
      -F variables[PARENT_PIPELINE_ID]="$CI_PIPELINE_ID" \
      -F variables[PARENT_PROJECT_ID]="$CI_PROJECT_ID" \
      -F variables[MR_TARGET_SHA]="$CI_MERGE_REQUEST_TARGET_BRANCH_SHA" \
      -F variables[MR_SOURCE_SHA]="$CI_MERGE_REQUEST_SOURCE_BRANCH_SHA" \
      -F variables[TESTS_TO_RUN_R4_ESSENSIUM]="$TESTS_TO_RUN_R4_ESSENSIUM" \
      -F variables[DEVICE_UNDER_TEST_R4_ESSENSIUM]="$DEVICE_UNDER_TEST_R4_ESSENSIUM" \
      ${CI_API_V4_URL}/projects/52461766/trigger/pipeline)
    - if [ $? -ne 0 ] ; then echo "Triggering external runner failed" && exit 1; fi
    - downstream_pipeline_url=$(echo "$trigger_details" | jq -e -r -c ".web_url")
    - echo "External builder running at ${downstream_pipeline_url}"
    - mkdir -p "build"
    - |
      # Checks if package file exists in the OSP package and fills the OSP_PACKAGE_FILE_ID var
      OSP_PACKAGE_FILE_ID=0
      check_package_file () {
          OSP_PACKAGE_FILE_ID=0
          local package_files=$(curl --fail --show-error --retry 3 -s --header "JOB-TOKEN: ${CI_JOB_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/${OSP_PACKAGE_ID}/package_files?per_page=100")
          OSP_PACKAGE_FILE_ID=$(echo "$package_files" | jq -e -c ".[] | select ( .file_name == \"${1}\") | .id" | sed -n \$p)
      }
      # Wait for successfull build start
      until check_package_file "${CI_PIPELINE_ID}.build_started"
      do
          sleep "$POLLING_RATE"
      done
      echo "Build started on external runner!"
      # Wait for successfull build
      until check_package_file "${CI_PIPELINE_ID}.build_success"
      do
          # Check if build failed
          if check_package_file "${CI_PIPELINE_ID}.build_failed" ; then
              echo "Build FAILED!" && exit 1
          fi
          sleep "$POLLING_RATE"
      done
    - echo "OSP build succeeded! Visit pipeline at ${downstream_pipeline_url}"
  needs: []
  timeout: 5h
  tags:
    - osp-build-fetch

build-for-cgr:
  stage: build
  variables:
    PRPLMESH_REVISION: $CI_COMMIT_SHA
  trigger:
    project: essensium-mind/prplmesh/puma7
    strategy: depend
  needs: []
  rules:
    - if: '$CI_PARENT_PIPELINE_SOURCE == "schedule" && $BUILD_CGR == "yes"'

test-upgrade-image-on-turris-omnia:
  extends: .test-upgrade-image
  variables:
    TARGET_DEVICE: turris-omnia
    TARGET_DEVICE_NAME: turris-omnia-1
    OPENWRT_IMAGE: "${TURRIS_OMNIA_FULLIMAGE}"
  needs: ["build-for-turris-omnia"]

test-upgrade-image-on-haze:
  extends: .test-upgrade-image
  variables:
    TARGET_DEVICE: haze
    TARGET_DEVICE_NAME: haze
    OPENWRT_IMAGE: "${HAZE_FULLIMAGE}"
  needs: ["build-for-haze"]

test-upgrade-image-on-turris-rdkb:
  extends: .test-upgrade-image
  variables:
    TARGET_DEVICE: turris-rdkb
    TARGET_DEVICE_NAME: turris-omnia-2
  script:
    - export RDKB_IMAGE_PATH=$(ls build/turris-omnia-rdk/rdkb-generic-broadband-image_rdkb*.rootfs.tar.gz)
    - export RDKB_IMAGE_NAME=${RDKB_IMAGE_PATH##*/}
    - tools/deploy_firmware.py --device turris-omnia-rdk --target-name "$TARGET_DEVICE_NAME" --image $RDKB_IMAGE_NAME --full --configuration ci/configuration/boardfarm/"$TARGET_DEVICE_NAME".sh
  needs: ["build-for-rdkb-turris-omnia"]

test-on-turris-omnia:
  extends: .test-on-target
  variables:
    TARGET_DEVICE: turris-omnia
    TARGET_DEVICE_NAME: turris-omnia-1
    OPENWRT_IMAGE: "${TURRIS_OMNIA_FULLIMAGE}"
  needs: ["build-for-turris-omnia"]

boardfarm-on-haze:
  extends: .test-on-target
  variables:
    TARGET_DEVICE: haze
    TARGET_DEVICE_NAME: haze
    OPENWRT_IMAGE: "${HAZE_FULLIMAGE}"
  script:
    - |
      echo "Retrieving the job ID for 'build-in-docker-legacy'."
      PARENT_PIPELINE_JOBS_URL="$CI_API_V4_URL/projects/$CI_PROJECT_ID/pipelines/$PARENT_PIPELINE_ID/jobs?per_page=100"
      echo "PARENT_PIPELINE_JOBS_URL: $PARENT_PIPELINE_JOBS_URL"
      BUILD_IN_DOCKER_JOB_ID=$(curl  --retry 3 --location --header "PRIVATE-TOKEN: $ARTIFACTS_DOWNLOADER_TOKEN" "$PARENT_PIPELINE_JOBS_URL" | jq -c '.[] | select( .name == "build-in-docker-legacy" ) | .id')
      echo "BUILD_IN_DOCKER_JOB_ID: $BUILD_IN_DOCKER_JOB_ID"
      BUILD_IN_DOCKER_DOWNLOAD_URL="$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/$BUILD_IN_DOCKER_JOB_ID/artifacts"
      echo "BUILD_IN_DOCKER_DOWNLOAD_URL: $BUILD_IN_DOCKER_DOWNLOAD_URL"
      echo "Downloading 'build-in-docker-legacy' artifacts."
      curl --location  --header "PRIVATE-TOKEN: $ARTIFACTS_DOWNLOADER_TOKEN" "$BUILD_IN_DOCKER_DOWNLOAD_URL" --output artifacts.zip
      unzip artifacts.zip && rm artifacts.zip
      echo Done
    - ssh "$TARGET_DEVICE_NAME" 'ubus-cli WiFi.Radio.*.Enable=1' |true
    - ./dctest.py --dut "$TARGET_DEVICE_NAME" --test-suite test_flows_on_prplwrt
    - ssh "$TARGET_DEVICE_NAME" 'service prplmesh stop && ubus-cli WiFi.Radio.*.Enable=0'| true
  tags:
    - boardfarm
    - haze
  needs:
    - build-for-haze

boardfarm-on-haze-stability:
  extends: boardfarm-on-haze
  parallel: 10
  rules:
    - if: '$STABILITY_TESTS == "yes"'
  retry: 0

boardfarm-on-turris-omnia-rdkb:
  extends: .test-on-rdkb
  variables:
    TARGET_DEVICE: turris-rdkb
    TARGET_DEVICE_NAME: turris-omnia-2
  script:
    - |
      echo "Retrieving the job ID for 'build-in-docker-legacy'."
      PARENT_PIPELINE_JOBS_URL="$CI_API_V4_URL/projects/$CI_PROJECT_ID/pipelines/$PARENT_PIPELINE_ID/jobs?per_page=100"
      echo "PARENT_PIPELINE_JOBS_URL: $PARENT_PIPELINE_JOBS_URL"
      BUILD_IN_DOCKER_JOB_ID=$(curl  --retry 3 --location --header "PRIVATE-TOKEN: $ARTIFACTS_DOWNLOADER_TOKEN" "$PARENT_PIPELINE_JOBS_URL" | jq -c '.[] | select( .name == "build-in-docker-legacy" ) | .id')
      echo "BUILD_IN_DOCKER_JOB_ID: $BUILD_IN_DOCKER_JOB_ID"
      BUILD_IN_DOCKER_DOWNLOAD_URL="$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/$BUILD_IN_DOCKER_JOB_ID/artifacts"
      echo "BUILD_IN_DOCKER_DOWNLOAD_URL: $BUILD_IN_DOCKER_DOWNLOAD_URL"
      echo "Downloading 'build-in-docker-legacy' artifacts."
      curl --location  --header "PRIVATE-TOKEN: $ARTIFACTS_DOWNLOADER_TOKEN" "$BUILD_IN_DOCKER_DOWNLOAD_URL" --output artifacts.zip
      unzip artifacts.zip && rm artifacts.zip
      echo Done
    - ssh "$TARGET_DEVICE_NAME" sed -ri 's/backhaul_wire_iface=erouter0/backhaul_wire_iface=lan4/' /opt/prplmesh/share/prplmesh_platform_db
    - ./dctest.py --dut $TARGET_DEVICE --test-suite test_flows_on_rdkb
  needs:
    - build-for-rdkb-turris-omnia

boardfarm-on-turris-omnia-rdkb-stability:
  extends: boardfarm-on-turris-omnia-rdkb
  parallel: 10
  rules:
    - if: '$STABILITY_TESTS == "yes"'
  retry: 0

run-certification-tests-R1-platform-essensium:
  extends: .run-certification-tests-R1
  before_script:
    - !reference [.run-certification-tests-R1, before_script]
    - echo "$TESTS_TO_RUN_ESSENSIUM" > .tests-to-run
    - echo "$DEVICE_UNDER_TEST_ESSENSIUM" > .device-under-test
  timeout: 14h
  tags:
    - certs-tests-essensium
  needs:
    - job: build-for-turris-omnia
    - job: build-for-haze
  rules:
    - if: '$TESTS_TO_RUN_ESSENSIUM !~ /^\$/ && $DEVICE_UNDER_TEST_ESSENSIUM != "prplmesh"'
    - when: manual
      allow_failure: true

run-certification-tests-R2-platform-essensium:
  extends: .run-certification-tests-R2
  before_script:
    - !reference [.run-certification-tests-R2, before_script]
    - echo "$TESTS_TO_RUN_R2_ESSENSIUM" > .tests-to-run
    - echo "$DEVICE_UNDER_TEST_R2_ESSENSIUM" > .device-under-test
  rules:
    - if: '$TESTS_TO_RUN_R2_ESSENSIUM !~ /^\$/ && $DEVICE_UNDER_TEST_R2_ESSENSIUM != "prplmesh"'
    - when: manual
      allow_failure: true
  timeout: 14h
  tags:
    - certs-tests-R2-essensium
  needs:
    - job: build-for-turris-omnia

run-certification-tests-R4-platform-essensium:
  extends: .run-certification-tests-R4
  before_script:
    - !reference [.run-certification-tests-R4, before_script]
    - echo "$TESTS_TO_RUN_R4_ESSENSIUM" > .tests-to-run
    - echo "$DEVICE_UNDER_TEST_R4_ESSENSIUM" > .device-under-test
  rules:
    - if: '$TESTS_TO_RUN_R4_ESSENSIUM !~ /^\$/ && $DEVICE_UNDER_TEST_R4_ESSENSIUM != "prplmesh" && $DEVICE_UNDER_TEST_R4_ESSENSIUM != "urx_osp" && $DEVICE_UNDER_TEST_R4_ESSENSIUM != "urx_ospv2"'
    - when: manual
      allow_failure: true
  timeout: 14h
  tags:
    - certs-tests-R4-essensium
  needs:
    - job: build-for-freedom

changelog:
  stage: build
  image: $CI_REGISTRY_IMAGE/prplmesh-scripts:$PARENT_PIPELINE_ID
  rules:
    - if: '$CI_COMMIT_TAG =~ /\A\d+\.\d+\.\d+\z/'
    - when: manual
      allow_failure: true
  needs:
    - pipeline: $PARENT_PIPELINE_ID
      job: image-build-scripts
  script:
    - tools/gen_changelog.py --latest-version --no-unreleased --no-preamble > CHANGELOG.md
  artifacts:
    paths:
      - CHANGELOG.md

upload-release-artifacts:
  stage: upload
  image: $CI_REGISTRY_IMAGE/prplmesh-scripts:$PARENT_PIPELINE_ID
  rules: *onrelease
  script:
    - |
      upload_command() {
        TARGET_REGISTRY_FLAG="";
        BUILD_FOLDER="build";
        # $1 is the target name under 'build/'. It will also be used for the name of the uploaded fullimage.
        export PACKAGE_REGISTRY_URL="${PACKAGE_REGISTRY_BASE_URL}/$1${TARGET_REGISTRY_FLAG}/${CI_COMMIT_TAG}"
        curl --fail --show-error --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file "${BUILD_FOLDER}/$1/prplmesh.ipk" "${PACKAGE_REGISTRY_URL}/prplmesh_${CI_COMMIT_TAG}_$1.ipk"
        # $2 is the name of the fullimage.
        curl --fail --show-error --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file "${BUILD_FOLDER}/$1/$2" "${PACKAGE_REGISTRY_URL}/$CI_COMMIT_TAG-$2"
      }
    - upload_command "turris-omnia" "$TURRIS_OMNIA_FULLIMAGE" "WHM"
    - upload_command "haze" "$HAZE_FULLIMAGE" "WHM"
    # need to get correct rdkb fullimage name
    - mv build/turris-omnia-rdk/rdkb-generic-broadband-image_rdkb*.rootfs.tar.gz build/turris-omnia-rdk/$TURRIS_OMNIA_RDKB_FULLIMAGE
    - mv build/turris-omnia-rdk/prplmesh_*.ipk build/turris-omnia-rdk/prplmesh.ipk
    - upload_command "turris-omnia-rdk" "$TURRIS_OMNIA_RDKB_FULLIMAGE" "WHM"
  needs:
    - job: build-for-turris-omnia
    - job: build-for-rdkb-turris-omnia
    - job: build-for-haze

release:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:v0.5.0
  rules: *onrelease
  script:
    - |
      release-cli create --name "Release $CI_COMMIT_TAG" --description CHANGELOG.md --tag-name $CI_COMMIT_TAG \
        --assets-link "{\"name\":\"turris-omnia prplmesh ipk\",\"type\":\"package\", \"url\":\"${PACKAGE_REGISTRY_BASE_URL}/turris-omnia/$CI_COMMIT_TAG/prplmesh_${CI_COMMIT_TAG}_turris-omnia.ipk\",\"link_type\":\"package\"}" \
        --assets-link "{\"name\":\"turris-omnia fullimage\",\"type\":\"image\", \"url\":\"${PACKAGE_REGISTRY_BASE_URL}/turris-omnia/$CI_COMMIT_TAG/$CI_COMMIT_TAG-$TURRIS_OMNIA_FULLIMAGE\",\"link_type\":\"image\"}" \
        --assets-link "{\"name\":\"haze prplmesh ipk\",\"type\":\"package\", \"url\":\"${PACKAGE_REGISTRY_BASE_URL}/haze/$CI_COMMIT_TAG/prplmesh_${CI_COMMIT_TAG}_haze.ipk\",\"link_type\":\"package\"}" \
        --assets-link "{\"name\":\"haze fullimage\",\"type\":\"image\", \"url\":\"${PACKAGE_REGISTRY_BASE_URL}/haze/$CI_COMMIT_TAG/$CI_COMMIT_TAG-$HAZE_FULLIMAGE\",\"link_type\":\"image\"}" \
        --assets-link "{\"name\":\"turris-omnia-rdk prplmesh ipk\",\"type\":\"package\", \"url\":\"${PACKAGE_REGISTRY_BASE_URL}/turris-omnia-rdk/$CI_COMMIT_TAG/prplmesh_${CI_COMMIT_TAG}_turris-omnia-rdk.ipk\",\"link_type\":\"package\"}" \
        --assets-link "{\"name\":\"turris-omnia-rdk fullimage\",\"type\":\"image\", \"url\":\"${PACKAGE_REGISTRY_BASE_URL}/turris-omnia-rdk/$CI_COMMIT_TAG/$CI_COMMIT_TAG-$TURRIS_OMNIA_RDKB_FULLIMAGE\",\"link_type\":\"image\"}"

  needs:
    - job: upload-release-artifacts
    - job: changelog
