// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// synopsys-check.groovy

pipeline {

  /* no label, executor is determined by JJB */
  agent {
    label "${params.executorNode}"
  }

  options {
      timeout(240)
  }

  stages {

    stage ("Clean workspace") {
      steps {
        sh 'rm -rf *'
      }
    }

    stage ("Get repo list") {
      steps {
        script {
          writeFile file: 'get_repo_list.py', text: """
#!/usr/bin/env python

import json
import os
import requests

if "github_organization" in os.environ:
    # this is a github org
    github_req = requests.get("https://api.github.com/orgs/%s/repos" %
                              os.environ["github_organization"])

    # pull out the "name" key out of each item
    repo_list = map(lambda item: item["name"], github_req.json())

else:
    # this is a gerrit server

    # fetch the list of projects
    gerrit_req = requests.get("%s/projects/?pp=0" %
                              os.environ["git_server_url"])
    # remove XSSI prefix
    # https://gerrit-review.googlesource.com/Documentation/rest-api.html#output
    gerrit_json = json.loads(gerrit_req.text.splitlines()[1])

    # remove repos which don't contain code
    repo_list = [repo for repo in gerrit_json.keys()
                 if repo not in ["All-Projects", "All-Users", "voltha-bal"]]

# sort and print
print(",".join(sorted(repo_list)))
"""

          /* this defines the variable globally - not ideal, but works - see:
          https://stackoverflow.com/questions/50571316/strange-variable-scoping-behavior-in-jenkinsfile
          */
          repos = sh(
            returnStdout: true,
            script: "python -u get_repo_list.py").trim().split(",")

          echo "repo list: ${repos}"
        }
      }
    }

    stage ("Checkout repos") {
      steps {
        script {
          repos.each { gitRepo ->
            sh "echo Checking out: ${gitRepo}"
            checkout(changelog: false, scm: [
                $class: 'GitSCM',
                userRemoteConfigs: [[
                  url: "${params.git_server_url}/${gitRepo}/",
                  name: "${branch}",
                ]],
                extensions: [
                  [$class: 'RelativeTargetDirectory', relativeTargetDir: "${gitRepo}"],
                  [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false],
                ],
              ])
          }
        }
      }
    }

    stage ("Synopsys Detect") {
      steps {
        script {
          repos.each { gitRepo ->
            sh "echo Running Synopsys Detect on: ${gitRepo}"
            synopsys_detect("--detect.source.path=${gitRepo} --detect.project.name=${blackduck_project}_${gitRepo} --detect.project.version.name=${branch} --detect.blackduck.signature.scanner.snippet.mode=true --detect.tools=ALL --detect.cleanup=false")
          }
        }
      }
    }

    stage ("Save logs") {
      steps {
        sh returnStdout: true, script: """
          echo COPYING LOGS
          mkdir -p bd_logs
          cp -r /home/jenkins/blackduck/runs/* bd_logs
          ls -l bd_logs/*/*
          """
        archiveArtifacts artifacts:'bd_logs/**/*.*'
      }
    }
  }
}
