#!/usr/bin/env groovy

pipeline {
  agent none

  stages {

    stage('Build') {
      agent {
        docker {
          image 'px4io/px4-dev-ros-melodic:2020-04-01'
          args '-e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw -e HOME=$WORKSPACE'
        }
      }
      steps {
        sh 'export'
        sh 'make distclean'
        sh 'ccache -s'
        sh 'git fetch --tags'
        sh 'make px4_sitl_default'
        sh 'make px4_sitl_default sitl_gazebo'
        sh 'make px4_sitl_default package'
        sh 'ccache -s'
        stash(name: "px4_sitl_package", includes: "build/px4_sitl_default/*.bz2")
        //archiveArtifacts(artifacts: "build/px4_sitl_default/*.bz2", fingerprint: true, onlyIfSuccessful: true)
      }
      post {
        always {
            sh 'make distclean'
        }
      }
    } // stage Build

    stage('ROS Tests') {
      steps {
        script {
          def missions = [
            [
              name: "FW",
              test: "mavros_posix_test_mission.test",
              mission: "FW_mission_1",
              vehicle: "plane"
            ],

            [
              name: "MC_box",
              test: "mavros_posix_test_mission.test",
              mission: "MC_mission_box",
              vehicle: "iris"
            ],
            [
              name: "MC_offboard_att",
              test: "mavros_posix_tests_offboard_attctl.test",
              mission: "",
              vehicle: "iris"
            ],
            [
              name: "MC_offboard_pos",
              test: "mavros_posix_tests_offboard_posctl.test",
              mission: "",
              vehicle: "iris"
            ],
            [
              name: "MC_offboard_rpyrt",
              test: "mavros_posix_tests_offboard_rpyrt_ctl.test",
              mission: "",
              vehicle: "iris"
            ],

            [
              name: "Rover 1",
              test: "mavros_posix_test_mission.test",
              mission: "rover_mission_1",
              vehicle: "rover"
            ],

            [
              name: "VTOL_standard",
              test: "mavros_posix_test_mission.test",
              mission: "VTOL_mission_1",
              vehicle: "standard_vtol"
            ],
            [
              name: "VTOL_tailsitter",
              test: "mavros_posix_test_mission.test",
              mission: "VTOL_mission_1",
              vehicle: "tailsitter"
            ],
            [
              name: "VTOL_tiltrotor",
              test: "mavros_posix_test_mission.test",
              mission: "VTOL_mission_1",
              vehicle: "tiltrotor"
            ],
            [
              name: "MC_avoidance",
              test: "mavros_posix_test_avoidance.test",
              mission: "avoidance",
              vehicle: "iris_obs_avoid",
              run_script: "rostest_avoidance_run.sh"
            ],
            [
              name: "MC_safe_landing",
              test: "mavros_posix_test_safe_landing.test",
              mission: "MC_safe_landing",
              vehicle: "iris_obs_avoid",
              run_script: "rostest_avoidance_run.sh"
            ],

          ]

          def test_nodes = [:]
          for (def i = 0; i < missions.size(); i++) {
            test_nodes.put(missions[i].name, createTestNode(missions[i]))
          }

          parallel test_nodes
        } // script
      } // steps
    } // stage ROS Tests

  } //stages

  environment {
    CCACHE_DIR = '/tmp/ccache'
    CI = true
    PX4_CMAKE_BUILD_TYPE = 'AddressSanitizer'
  }

  options {
    buildDiscarder(logRotator(numToKeepStr: '10', artifactDaysToKeepStr: '20'))
    timeout(time: 60, unit: 'MINUTES')
  }
} // pipeline

def createTestNode(Map test_def) {
  return {
    node {
      cleanWs()
      docker.image("px4io/px4-dev-ros-melodic:2020-04-01").inside('-e HOME=${WORKSPACE}') {
        stage(test_def.name) {
          def run_script = test_def.get('run_script', 'rostest_px4_run.sh')
          def test_ok = true
          sh('export')

          unstash('px4_sitl_package')
          sh('tar -xjpvf build/px4_sitl_default/px4-px4_sitl_default*.bz2')

          // run test
          try {
            sh('px4-px4_sitl_default*/px4/test/' + run_script + ' ' + test_def.test + ' mission:=' + test_def.mission + ' vehicle:=' + test_def.vehicle)

          } catch (exc) {
            // save all test artifacts for debugging
            archiveArtifacts(allowEmptyArchive: false, artifacts: '.ros/**/*.ulg, .ros/**/rosunit-*.xml, .ros/**/rostest-*.log')
            test_ok = false
          }

          // upload log to flight review (https://logs.px4.io/)
          sh('px4-px4_sitl_default*/px4/Tools/upload_log.py -q --description "${JOB_NAME}: ${STAGE_NAME}" --feedback "${JOB_NAME} ${CHANGE_TITLE} ${CHANGE_URL}" --source CI .ros/log/*/*.ulg')

          // log analysis
          // process ekf log data
          try {
            sh('px4-px4_sitl_default*/px4/Tools/ecl_ekf/process_logdata_ekf.py .ros/log/*/*.ulg')
          } catch (exc) {
            // save log analysis artifacts for debugging
            archiveArtifacts(allowEmptyArchive: false, artifacts: '.ros/**/*.pdf, .ros/**/*.csv')
            // FIXME: don't let the script to fail the build
            // test_ok = false
          }

          if (!test_ok) {
            error('ROS Test failed')
          }
        } // stage
        cleanWs()
      } // docker.image
    } // node
  } // return
} // createTestNode
