#!/usr/bin/env groovy

List<String> getSupportedBoards() {
    return [
        'enterprise',
        'excelsior'
    ]
}

String generateDateStamp() {
    def date = new Date()
    return date.format("yyyyMMdd-HHmmss")
}

String getLatestSnapshot(repository_stem) {
    def script = """
        aptly snapshot list --sort=time --raw \
            | grep -E '^${repository_stem}-[0-9]' \
            | tail -n1
    """

    return sh(returnStdout: true, script: script).trim()
}

String getSnapshotFromPublish(releaseName, repoName, component) {
    def script = "aptly publish show ${releaseName} filesystem:public:${repoName} | grep -E '^  ${component}: .*' | grep 'snapshot' | awk '{ print \$2 }'"

    return sh(returnStdout: true, script: script).trim()
}

def installGpgKeyring() {
    sh """
       install -d -m 700 -o root -g root /var/lib/aptly/.gnupg
       tar -C /var/lib/aptly/.gnupg -zxf /var/lib/aptly/keyring/release-keyring.tar.gz
       chown -R root:root /var/lib/aptly/.gnupg
       find /var/lib/aptly/.gnupg -type d -exec chmod 700 '{}' ';'
       find /var/lib/aptly/.gnupg -type f -exec chmod 600 '{}' ';'
       """
}

def initSourceTree(boardName, needsNative = false) {
    sh """
       /opt/gcompute-tools/git-cookie-authdaemon

       git config --global url.https://aiyprojects.googlesource.com/.insteadOf sso://aiyprojects/
       git config --global url.https://excelsior.googlesource.com/.insteadOf sso://excelsior/

       mkdir -p .repo/local_manifests
       mkdir -p cache
       chmod 777 cache .repo/local_manifests
       """


    timeout(time: 20, unit: 'MINUTES') {
        checkout([$class: 'RepoScm',
                  currentBranch: true,
                  jobs: 24,
                  manifestRepositoryUrl: manifestUrlFromBoardName(boardName),
                  manifestBranch: 'master',
                  manifestFile: "${boardName}.xml",
                  manifestGroup: "default,internal",
                  depth: 1,
                  quiet: true])
    }

    // Bring in the pbuilder tarballs.
    //
    // archiveArtifacts includes the relative path to the
    // files we archive, so we don't have to specify cache/
    // here in the target.
    copyArtifacts(projectName: 'global.pbuilder.arm64', filter: '**/*.tgz')
    copyArtifacts(projectName: 'global.pbuilder.armhf', filter: '**/*.tgz')
    copyArtifacts(projectName: 'global.pbuilder.cross', filter: '**/*.tgz')
}

def buildTarget(targetName) {
    def nprocs = sh(returnStdout: true, script: 'nproc').trim()
    sh "bash -c 'source build/setup.sh; m -j${nprocs} ${targetName}; exit \$?'"
}

def manifestUrlFromBoardName(boardName) {
    switch (boardName) {
        case "excelsior":
        case "enterprise":
            return "http://coral.googlesource.com/manifest"
        default:
            error "Unknown board ${boardName}"
    }
}

def nameFromRepoType(repoType, boardName) {
    if (repoType == "core") {
        return "core"
    } else if (repoType == "bsp") {
        return "bsp-${boardName}"
    } else {
        error 'Unknown repoType ${repoType}'
    }
}

def uploadAllGeneratedPackages(repoType, boardName, packageNames, includeSources = true) {
    def outPath = repoType
    def repoName = nameFromRepoType(repoType, boardName)
    def packageFilenames = []

    echo "Packages to upload are: ${packageNames}"

    for (packageName in packageNames) {
        def packages = findFiles(glob: "out/**/${packageName}*.deb")
        def sources  = []

        if (includeSources == true) {
            sources = findFiles(glob: "out/**/${packageName}*.dsc")
        }
        
        def filenames = (packages + sources).each{entry -> entry.path}
        packageFilenames.addAll(filenames)
    }


    if (packageFilenames.size() == 0) {
        error 'No packages were found! Assuming failed build.'
    }

    def date = new Date()
    String stamp = date.format("yyyyMMdd-HHmmss")

    sh """
       aptly task run repo add -force-replace unstable-${repoName} ${packageFilenames.join(' ')}, \
                      snapshot create unstable-${repoName}-${stamp} from repo unstable-${repoName}
       """
}

def buildPackagePipeline(boardName, repoType, targetName, packageNames, needsNative = false, includeSources = true) {
    def workspacePath = "/home/jenkins/workspace"
    def buildLabel = "${targetName}-${UUID.randomUUID().toString()}"
    def sourcePath = "${workspacePath}/src"

    // FIXME(jtgans): Get rid of privileged! This is a security risk!
    def jnlpContainer = containerTemplate(name: 'jnlp',
                                          image: 'jenkins/jnlp-slave:alpine')
    def debianContainer = containerTemplate(name: 'debian',
                                            image: 'gcr.io/mendel-linux-cloud-infra/mendel-builder:latest',
                                            command: 'cat',
                                            args: '',
                                            ttyEnabled: true,
                                            privileged: true)
    def aptlyVolume = persistentVolumeClaim(claimName: 'aptly-state', mountPath: '/var/lib/aptly')

    podTemplate(label: buildLabel, containers: [jnlpContainer, debianContainer], volumes: [aptlyVolume], envVars: []) {
        node(buildLabel) {
            dir(sourcePath) {
                container('debian') {
                    stage('Init') {
                        initSourceTree(boardName, needsNative)
                        sh "bash -c 'source build/setup.sh; m prereqs; exit \$?'"
                    }

                    stage('Build') {
                        buildTarget(targetName)
                    }

                    stage('Deploy') {
                        sh 'ls '
                        uploadAllGeneratedPackages(repoType, boardName, packageNames, includeSources)
                    }
                }
            }
        }
    }
}

String coreIsPublished(String releaseName) {
    def script = "aptly publish list --raw |grep -E '^filesystem:public:${releaseName} ${releaseName}' || true"
    String publishName = sh(returnStdout: true, script: script).trim()
    return (publishName != "")
}

String bspIsPublished(String releaseName, String boardName) {
    def script = "aptly publish list --raw |grep -E '^filesystem:public:${releaseName}-bsp-${boardName} ${releaseName}' || true"
    String publishName = sh(returnStdout: true, script: script).trim()
    return (publishName != "")
}
