//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

// Import the utility functionality.
import jobs.generation.Utilities

// Grab the github project name passed in
def project = GithubProject
def branch = GithubBranchName

def msbuildTypeMap = [
    'debug':'chk',
    'test':'test',
    'release':'fre'
]

// convert `machine` parameter to OS component of PR task name
def machineTypeToOSTagMap = [
    'Windows_NT': 'Windows',        // Windows Server 2012 R2, equivalent to Windows 8.1 (aka Blue)
    'Ubuntu16.04': 'Ubuntu',
    'OSX10.12': 'OSX'
]

def dailyRegex = 'dailies'

// ---------------
// HELPER CLOSURES
// ---------------

def CreateBuildTask = { isPR, buildArch, buildType, machine, configTag, buildExtra, testExtra, runCodeAnalysis, excludeConfigIf, nonDefaultTaskSetup ->
    if (excludeConfigIf && excludeConfigIf(isPR, buildArch, buildType)) {
        return // early exit: we don't want to create a job for this configuration
    }

    def config = "${buildArch}_${buildType}"
    config = (configTag == null) ? config : "${configTag}_${config}"

    // params: Project, BaseTaskName, IsPullRequest (appends '_prtest')
    def jobName = Utilities.getFullJobName(project, config, isPR)

    def testableConfig = buildType in ['debug', 'test'] && buildArch != 'arm'
    def analysisConfig = buildType in ['release'] && runCodeAnalysis

    def buildScript = "call .\\jenkins\\buildone.cmd ${buildArch} ${buildType} "
    buildScript += buildExtra ?: ''
    buildScript += analysisConfig ? ' "/p:runcodeanalysis=true"' : ''
    def testScript = "call .\\jenkins\\testone.cmd ${buildArch} ${buildType} "
    testScript += testExtra ?: ''
    def analysisScript = '.\\Build\\scripts\\check_prefast_error.ps1 . CodeAnalysis.err'

    def newJob = job(jobName) {
        // This opens the set of build steps that will be run.
        // This looks strange, but it is actually a method call, with a
        // closure as a param, since Groovy allows method calls without parens.
        // (Compare with '.each' method used above.)
        steps {
            batchFile(buildScript) // run the parameter as if it were a batch file
            if (testableConfig) {
                batchFile(testScript)
            }
            if (analysisConfig) {
                powerShell(analysisScript)
            }
        }
    }

    def msbuildType = msbuildTypeMap.get(buildType)
    def msbuildFlavor = "build_${buildArch}${msbuildType}"
    def archivalString = "test/${msbuildFlavor}.*,test/logs/**"
    archivalString += analysisConfig ? ',CodeAnalysis.err' : ''
    Utilities.addArchival(newJob, archivalString,
        '', // no exclusions from archival
        false, // doNotFailIfNothingArchived=false ~= failIfNothingArchived
        false) // archiveOnlyIfSuccessful=false ~= archiveAlways

    Utilities.setMachineAffinity(newJob, machine, 'latest-or-auto')
    Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")

    if (nonDefaultTaskSetup == null) {
        if (isPR) {
            def osTag = machineTypeToOSTagMap.get(machine)
            Utilities.addGithubPRTriggerForBranch(newJob, branch, "${osTag} ${config}")
        } else {
            Utilities.addGithubPushTrigger(newJob)
        }
    } else {
        // nonDefaultTaskSetup is e.g. DailyBuildTaskSetup (which sets up daily builds)
        // These jobs will only be configured for the branch specified below,
        // which is the name of the branch netci.groovy was processed for.
        // See list of such branches at:
        // https://github.com/dotnet/dotnet-ci/blob/master/jobs/data/repolist.txt
        nonDefaultTaskSetup(newJob, isPR, config)
    }
}

def CreateBuildTasks = { machine, configTag, buildExtra, testExtra, runCodeAnalysis, excludeConfigIf, nonDefaultTaskSetup ->
    [true, false].each { isPR ->
        ['x86', 'x64', 'arm'].each { buildArch ->
            ['debug', 'test', 'release'].each { buildType ->
                CreateBuildTask(isPR, buildArch, buildType, machine, configTag, buildExtra, testExtra, runCodeAnalysis, excludeConfigIf, nonDefaultTaskSetup)
            }
        }
    }
}

def CreateXPlatBuildTask = { isPR, buildType, staticBuild, machine, platform, configTag,
    xplatBranch, nonDefaultTaskSetup, customOption, testVariant, extraBuildParams ->

    def config = (platform == "osx" ? "osx_${buildType}" : "linux_${buildType}")
    def numConcurrentCommand = (platform == "osx" ? "sysctl -n hw.logicalcpu" : "nproc")

    config = (configTag == null) ? config : "${configTag}_${config}"
    config = staticBuild ? "static_${config}" : "shared_${config}"
    config = customOption ? customOption.replaceAll(/[-]+/, "_") + "_" + config : config

    // params: Project, BaseTaskName, IsPullRequest (appends '_prtest')
    def jobName = Utilities.getFullJobName(project, config, isPR)

    def infoScript = "bash jenkins/get_system_info.sh --${platform}"
    def buildFlag = buildType == "release" ? "" : (buildType == "debug" ? "--debug" : "--test-build")
    def staticFlag = staticBuild ? "--static" : ""
    def swbCheckFlag = (platform == "linux" && buildType == "debug" && !staticBuild) ? "--wb-check" : "";
    def icuFlag = (platform == "osx" ? "--icu=/usr/local/opt/icu4c/include" : "")
    def compilerPaths = (platform == "osx") ? "" : "--cxx=/usr/bin/clang++-3.9 --cc=/usr/bin/clang-3.9"
    def buildScript = "bash ./build.sh ${staticFlag} -j=`${numConcurrentCommand}` ${buildFlag} " +
                      "${swbCheckFlag} ${compilerPaths} ${icuFlag} ${customOption} ${extraBuildParams}"
    def testScript = "bash test/runtests.sh \"${testVariant}\""

    def newJob = job(jobName) {
        steps {
            shell(infoScript)
            shell(buildScript)
            shell(testScript)
        }
    }

    def archivalString = "out/build.log"
    Utilities.addArchival(newJob, archivalString,
        '', // no exclusions from archival
        true, // doNotFailIfNothingArchived=false ~= failIfNothingArchived (true ~= doNotFail)
        false) // archiveOnlyIfSuccessful=false ~= archiveAlways

    Utilities.setMachineAffinity(newJob, machine, 'latest-or-auto')
    Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")

    if (nonDefaultTaskSetup == null) {
        if (isPR) {
            def osTag = machineTypeToOSTagMap.get(machine)
            Utilities.addGithubPRTriggerForBranch(newJob, xplatBranch, "${osTag} ${config}")
        } else {
            Utilities.addGithubPushTrigger(newJob)
        }
    } else {
        // nonDefaultTaskSetup is e.g. DailyBuildTaskSetup (which sets up daily builds)
        // These jobs will only be configured for the branch specified below,
        // which is the name of the branch netci.groovy was processed for.
        // See list of such branches at:
        // https://github.com/dotnet/dotnet-ci/blob/master/jobs/data/repolist.txt
        nonDefaultTaskSetup(newJob, isPR, config)
    }
}

// Generic task to trigger clang-based cross-plat build tasks
def CreateXPlatBuildTasks = { machine, platform, configTag, xplatBranch, nonDefaultTaskSetup, extraBuildParams ->
    [true, false].each { isPR ->
        CreateXPlatBuildTask(isPR, "test", "", machine, platform,
            configTag, xplatBranch, nonDefaultTaskSetup, "--no-jit", "--variants disable_jit", extraBuildParams)

        ['debug', 'test', 'release'].each { buildType ->
            def staticBuildConfigs = [true, false]
            if (platform == "osx") {
                staticBuildConfigs = [true]
            }

            staticBuildConfigs.each { staticBuild ->
                CreateXPlatBuildTask(isPR, buildType, staticBuild, machine, platform,
                    configTag, xplatBranch, nonDefaultTaskSetup, "", "", extraBuildParams)
            }
        }
    }
}

def DailyBuildTaskSetup = { newJob, isPR, triggerName, groupRegex ->
    // The addition of triggers makes the job non-default in GitHub.
    if (isPR) {
        def triggerRegex = "(${dailyRegex}|${groupRegex}|${triggerName})"
        Utilities.addGithubPRTriggerForBranch(newJob, branch,
            triggerName, // GitHub task name
            "(?i).*test\\W+${triggerRegex}.*")
    } else {
        Utilities.addPeriodicTrigger(newJob, '@daily')
    }
}

def CreateStyleCheckTasks = { taskString, taskName, checkName ->
    [true, false].each { isPR ->
        def jobName = Utilities.getFullJobName(project, taskName, isPR)

        def newJob = job(jobName) {
            steps {
                shell(taskString)
            }
        }

        Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
        if (isPR) {
            // Set PR trigger.
            Utilities.addGithubPRTriggerForBranch(newJob, branch, checkName)
        } else {
            // Set a push trigger
            Utilities.addGithubPushTrigger(newJob)
        }

        Utilities.setMachineAffinity(newJob, 'Ubuntu16.04', 'latest-or-auto')
    }
}

// ----------------
// INNER LOOP TASKS
// ----------------

CreateBuildTasks('Windows_NT', null, null, "-winBlue", true, null, null)

// Add some additional daily configs to trigger per-PR as a quality gate:
// x64_debug Slow Tests
CreateBuildTask(true, 'x64', 'debug',
    'Windows_NT', 'ci_slow', null, '-winBlue -includeSlow', false, null, null)
// x64_debug DisableJIT
CreateBuildTask(true, 'x64', 'debug',
    'Windows_NT', 'ci_disablejit', '"/p:BuildJIT=false"', '-winBlue -disablejit', false, null, null)
// x64_debug Lite
CreateBuildTask(true, 'x64', 'debug',
    'Windows_NT', 'ci_lite', '"/p:BuildLite=true"', '-winBlue -lite', false, null, null)

// -----------------
// DAILY BUILD TASKS
// -----------------

if (!branch.endsWith('-ci')) {
    // build and test on the usual configuration (VS 2015) with -includeSlow
    CreateBuildTasks('Windows_NT', 'daily_slow', null, '-winBlue -includeSlow', false,
        /* excludeConfigIf */ null,
        /* nonDefaultTaskSetup */ { newJob, isPR, config ->
            DailyBuildTaskSetup(newJob, isPR,
                "Windows ${config}",
                'slow\\s+tests')})

    // build and test on the usual configuration (VS 2015) with JIT disabled
    CreateBuildTasks('Windows_NT', 'daily_disablejit', '"/p:BuildJIT=false"', '-winBlue -disablejit', true,
        /* excludeConfigIf */ null,
        /* nonDefaultTaskSetup */ { newJob, isPR, config ->
            DailyBuildTaskSetup(newJob, isPR,
                "Windows ${config}",
                '(disablejit|nojit)\\s+tests')})
}

// ----------------
// CODE STYLE TASKS
// ----------------

CreateStyleCheckTasks('./jenkins/check_copyright.sh', 'ubuntu_check_copyright', 'Copyright Check')
CreateStyleCheckTasks('./jenkins/check_eol.sh', 'ubuntu_check_eol', 'EOL Check')
CreateStyleCheckTasks('./jenkins/check_tabs.sh', 'ubuntu_check_tabs', 'Tab Check')

// --------------
// XPLAT BRANCHES
// --------------

// Explicitly enumerate xplat-incompatible branches, because we don't anticipate any future incompatible branches
def isXPlatCompatibleBranch = !(branch in ['release/1.1', 'release/1.1-ci', 'release/1.2', 'release/1.2-ci'])

// Include these explicitly-named branches
def isXPlatDailyBranch = branch in ['master', 'linux', 'xplat']
// Include some release/* branches (ignore branches ending in '-ci')
if (branch.startsWith('release') && !branch.endsWith('-ci')) {
    // Allows all current and future release/* branches on which we should run daily builds of XPlat configs.
    // RegEx matches branch names we should ignore (e.g. release/1.1, release/1.2, release/1.2-pre)
    includeReleaseBranch = !(branch =~ /^release\/(1\.[12](\D.*)?)$/)
    isXPlatDailyBranch |= includeReleaseBranch
}

// -----------------
// LINUX BUILD TASKS
// -----------------

if (isXPlatCompatibleBranch) {
    def osString = 'Ubuntu16.04'

    // PR and CI checks
    CreateXPlatBuildTasks(osString, "linux", "ubuntu", branch, null, "")

    // Create a PR/continuous task to check ubuntu/static/debug/no-icu
    [true, false].each { isPR -> 
        CreateXPlatBuildTask(isPR, "debug", true, osString, "linux",
            "ubuntu", branch, null, "--no-icu", "--not-tag exclude_noicu", "")
    }

    // daily builds
    if (isXPlatDailyBranch) {
        CreateXPlatBuildTasks(osString, "linux", "daily_ubuntu", branch,
            /* nonDefaultTaskSetup */ { newJob, isPR, config ->
                DailyBuildTaskSetup(newJob, isPR,
                    "Ubuntu ${config}",
                    'linux\\s+tests')},
            /* extraBuildParams */ "--extra-defines=PERFMAP_TRACE_ENABLED=1")
    }
}

// ---------------
// OSX BUILD TASKS
// ---------------

if (isXPlatCompatibleBranch) {
    def osString = 'OSX10.12'

    // PR and CI checks
    CreateXPlatBuildTasks(osString, "osx", "osx", branch, null, "")

    // daily builds
    if (isXPlatDailyBranch) {
        CreateXPlatBuildTasks(osString, "osx", "daily_osx", branch,
            /* nonDefaultTaskSetup */ { newJob, isPR, config ->
                DailyBuildTaskSetup(newJob, isPR,
                    "OSX ${config}",
                    'linux\\s+tests')},
            /* extraBuildParams */ "")
    }
}

// ------------
// HELP MESSAGE
// ------------

Utilities.createHelperJob(this, project, branch,
    "Welcome to the ${project} Repository",  // This is prepended to the help message
    "For additional documentation on ChakraCore CI checks, please see:\n" +
    "\n" +
    "* https://github.com/Microsoft/ChakraCore/wiki/Jenkins-CI-Checks\n" +
    "* https://github.com/Microsoft/ChakraCore/wiki/Jenkins-Build-Triggers\n" +
    "* https://github.com/Microsoft/ChakraCore/wiki/Jenkins-Repro-Steps\n" +
    "\n" +
    "Have a nice day!")  // This is appended to the help message.  You might put known issues here.
