import jetbrains.buildServer.configs.kotlin.v2018_2.*
import jetbrains.buildServer.configs.kotlin.v2018_2.buildFeatures.commitStatusPublisher
import jetbrains.buildServer.configs.kotlin.v2018_2.buildFeatures.dockerSupport
import jetbrains.buildServer.configs.kotlin.v2018_2.buildSteps.dockerCommand
import jetbrains.buildServer.configs.kotlin.v2018_2.buildSteps.script
import jetbrains.buildServer.configs.kotlin.v2018_2.triggers.vcs
import jetbrains.buildServer.configs.kotlin.v2018_2.vcs.GitVcsRoot

/*
The settings script is an entry point for defining a TeamCity
project hierarchy. The script should contain a single call to the
project() function with a Project instance or an init function as
an argument.

VcsRoots, BuildTypes, Templates, and subprojects can be
registered inside the project using the vcsRoot(), buildType(),
template(), and subProject() methods respectively.

To debug settings scripts in command-line, run the

    mvnDebug org.jetbrains.teamcity:teamcity-configs-maven-plugin:generate

command and attach your debugger to the port 8000.

To debug in IntelliJ Idea, open the 'Maven Projects' tool window (View
-> Tool Windows -> Maven Projects), find the generate task node
(Plugins -> teamcity-configs -> teamcity-configs:generate), the
'Debug' option is available in the context menu for the task.
*/

version = "2019.1"

project {
    description = "TroutCreek Runners TeamCity Project"

    vcsRoot(ProjectSourceRoot)
    vcsRoot(GitGitAwsInternalJustinTvBuilderProductsTroutcreekRunnersGit)

    buildType(RunLintingChecks)
    buildType(RunTests)
    buildType(PrepareBuildDependencies)
    buildType(InitializeBuildChain)

    params {
        text("ecr.repo.dependencies", "troutcreek-runners-build-dependencies", label = "ECR Repository", description = "The name used the ECR Repository", display = ParameterDisplay.HIDDEN, readOnly = true)
        text("git.branch.spec", """
            +:refs/heads/*
            +:refs/tags/*
            +:refs/(pull/*)/head
        """.trimIndent(), label = "Branch Spec", description = "What branches should we additionally watch or ignore?", display = ParameterDisplay.HIDDEN)
        text("git.branch.default", "refs/heads/master", label = "Default Branch", description = "What branch to treat as the default for a given build configuration.", display = ParameterDisplay.HIDDEN)
        text("teamcity.vcsTrigger.runBuildInNewEmptyBranch", "true", label = "Trigger Empty Branches", description = "Should cause Teamcity to run builds when re-tagging the same commit.", display = ParameterDisplay.HIDDEN)
    }

    features {
        feature {
            id = "994136867826PDX"
            type = "OAuthProvider"
            param("aws.use.default.credential.provider.chain", "true")
            param("displayName", "Amazon ECR (994136867826 PDX)")
            param("aws.credentials.type", "aws.access.keys")
            param("aws.region.name", "us-west-2")
            param("registryId", "994136867826")
            param("providerType", "AmazonDocker")
        }
    }
    buildTypesOrder = arrayListOf(InitializeBuildChain, PrepareBuildDependencies, RunLintingChecks, RunTests)
}

object InitializeBuildChain : BuildType({
    name = "Initialize Build Chain"

    params {
        text("git.version", "", label = "Git Version", description = "The version as determined by git tag inspection.", display = ParameterDisplay.HIDDEN)
        text("git.commit.short", "", label = "Git Short Hash", description = "The short hash of the commit inspected.", display = ParameterDisplay.HIDDEN)
    }

    vcs {
        root(ProjectSourceRoot)

        cleanCheckout = true
    }

    steps {
        script {
            name = "Discover Version Number"
            scriptContent = """
                #!/usr/bin/env ruby
                # frozen_string_literal: true
                
                tag = `git describe --tags --exact-match --match %teamcity.build.branch% 2> /dev/null`.strip
                hash = `git rev-parse HEAD 2> /dev/null`.strip[0..6]
                
                version = tag.empty? ? hash : tag
                
                puts "##teamcity[setParameter name='git.version' value='#{version}']"
                puts "##teamcity[setParameter name='git.commit.short' value='#{hash}']"
                puts "##teamcity[buildNumber '#{version}']"
            """.trimIndent()
        }
        script {
            name = "Verify '%ecr.repo.dependencies%' ECR Repo"
            scriptContent = """
                #!/usr/bin/env bash
                echo "Validating %ecr.repo.dependencies%..."
                aws --region us-west-2 ecr describe-repositories --repository-names %ecr.repo.dependencies% > /dev/null 2>&1
                if [[ ${'$'}? -ne 0 ]]; then
                    echo "Repository doesn't exist! creating it..."
                    aws --region us-west-2 ecr create-repository --repository-name %ecr.repo.dependencies%
                fi
            """.trimIndent()
        }
    }
})

object PrepareBuildDependencies : BuildType({
    name = "Prepare Build Dependencies"

    buildNumberPattern = "${InitializeBuildChain.depParamRefs.buildNumber}"

    params {
        text("git.version", "${InitializeBuildChain.depParamRefs["git.version"]}", label = "Git Version", description = "The version as determined by git tag inspection.", display = ParameterDisplay.HIDDEN, readOnly = true)
        text("git.commit.short", "${InitializeBuildChain.depParamRefs["git.commit.short"]}", label = "Git Short Hash", description = "The short hash of the commit inspected.", display = ParameterDisplay.HIDDEN, readOnly = true)
        text("ecr.domain", "994136867826.dkr.ecr.us-west-2.amazonaws.com", label = "ECR Domain", display = ParameterDisplay.HIDDEN)
    }

    vcs {
        root(ProjectSourceRoot)

        cleanCheckout = true
    }

    steps {
        dockerCommand {
            name = "Build Docker Image"
            commandType = build {
                source = path {
                    path = "Dockerfile"
                }
                namesAndTags = "994136867826.dkr.ecr.us-west-2.amazonaws.com/%ecr.repo.dependencies%:%git.commit.short%"
                commandArgs = " --target build --pull"
            }
        }
        dockerCommand {
            name = "Push Docker Image"
            commandType = push {
                namesAndTags = "994136867826.dkr.ecr.us-west-2.amazonaws.com/%ecr.repo.dependencies%:%git.commit.short%"
            }
        }
    }

    triggers {
        vcs {
        }
    }

    features {
        commitStatusPublisher {
            vcsRootExtId = "${ProjectSourceRoot.id}"
            publisher = github {
                githubUrl = "https://git-aws.internal.justin.tv/api/v3"
                authType = personalToken {
                    token = "credentialsJSON:06c8cbc2-4163-4856-a7b1-e768875cd57d"
                }
            }
        }
        dockerSupport {
            cleanupPushedImages = true
            loginToRegistry = on {
                dockerRegistryId = "994136867826PDX"
            }
        }
    }

    dependencies {
        snapshot(InitializeBuildChain) {
            onDependencyFailure = FailureAction.CANCEL
            onDependencyCancel = FailureAction.CANCEL
        }
    }
})

object RunLintingChecks : BuildType({
    name = "Run Linting Checks"

    buildNumberPattern = "${PrepareBuildDependencies.depParamRefs.buildNumber}"

    params {
        text("git.version", "${PrepareBuildDependencies.depParamRefs["git.version"]}", label = "Git Version", description = "The version as determined by git tag inspection.", display = ParameterDisplay.HIDDEN, readOnly = true)
        text("git.commit.short", "${PrepareBuildDependencies.depParamRefs["git.commit.short"]}", label = "Git Short Hash", description = "The short hash of the commit inspected.", display = ParameterDisplay.HIDDEN, readOnly = true)
        text("ecr.domain", "994136867826.dkr.ecr.us-west-2.amazonaws.com", label = "ECR Domain", display = ParameterDisplay.HIDDEN)
    }

    vcs {
        root(ProjectSourceRoot)

        cleanCheckout = true
    }

    steps {
        script {
            name = "Run Linting Tests"
            scriptContent = "make lint"
            dockerImage = "%ecr.domain%/%ecr.repo.dependencies%:%git.commit.short%"
            dockerPull = true
            dockerRunParameters = "-e TEAMCITY_VERSION"
        }
    }

    triggers {
        vcs {
            branchFilter = """
                +:*
                -:<default>
            """.trimIndent()
        }
    }

    features {
        commitStatusPublisher {
            vcsRootExtId = "${ProjectSourceRoot.id}"
            publisher = github {
                githubUrl = "https://git-aws.internal.justin.tv/api/v3"
                authType = personalToken {
                    token = "credentialsJSON:06c8cbc2-4163-4856-a7b1-e768875cd57d"
                }
            }
        }
        dockerSupport {
            cleanupPushedImages = true
            loginToRegistry = on {
                dockerRegistryId = "994136867826PDX"
            }
        }
    }

    dependencies {
        snapshot(PrepareBuildDependencies) {
            onDependencyFailure = FailureAction.CANCEL
            onDependencyCancel = FailureAction.CANCEL
        }
    }
})

object RunTests : BuildType({
    name = "Run Tests"

    buildNumberPattern = "${RunLintingChecks.depParamRefs.buildNumber}"

    params {
        text("git.version", "${RunLintingChecks.depParamRefs["git.version"]}", label = "Git Version", description = "The version as determined by git tag inspection.", display = ParameterDisplay.HIDDEN, readOnly = true)
        text("git.commit.short", "${RunLintingChecks.depParamRefs["git.commit.short"]}", label = "Git Short Hash", description = "The short hash of the commit inspected.", display = ParameterDisplay.HIDDEN, readOnly = true)
        text("ecr.domain", "994136867826.dkr.ecr.us-west-2.amazonaws.com", label = "ECR Domain", display = ParameterDisplay.HIDDEN)
    }

    vcs {
        root(ProjectSourceRoot)

        cleanCheckout = true
    }

    steps {
        script {
            name = "Run Linting Tests"
            scriptContent = "make test"
            dockerImage = "%ecr.domain%/%ecr.repo.dependencies%:%git.commit.short%"
            dockerPull = true
            dockerRunParameters = "-e TEAMCITY_VERSION"
        }
    }

    triggers {
        vcs {
            branchFilter = """
                +:*
                -:<default>
            """.trimIndent()
        }
    }

    features {
        commitStatusPublisher {
            vcsRootExtId = "${ProjectSourceRoot.id}"
            publisher = github {
                githubUrl = "https://git-aws.internal.justin.tv/api/v3"
                authType = personalToken {
                    token = "credentialsJSON:06c8cbc2-4163-4856-a7b1-e768875cd57d"
                }
            }
        }
        dockerSupport {
            cleanupPushedImages = true
            loginToRegistry = on {
                dockerRegistryId = "994136867826PDX"
            }
        }
    }

    dependencies {
        snapshot(RunLintingChecks) {
            onDependencyFailure = FailureAction.CANCEL
            onDependencyCancel = FailureAction.CANCEL
        }
    }
})

object GitGitAwsInternalJustinTvBuilderProductsTroutcreekRunnersGit : GitVcsRoot({
    name = "git@git-aws.internal.justin.tv:builder-products/troutcreek-runners.git"
    url = "git@git-aws.internal.justin.tv:builder-products/troutcreek-runners.git"
    authMethod = uploadedKey {
        userName = "git"
        uploadedKey = "id_rsa_teamcity"
    }
})

object ProjectSourceRoot : GitVcsRoot({
    name = "Project Source"
    url = "git@git-aws.internal.justin.tv:builder-products/troutcreek-runners.git"
    branch = "%git.branch.default%"
    branchSpec = "%git.branch.spec%"
    useTagsAsBranches = true
    authMethod = uploadedKey {
        uploadedKey = "id_rsa_teamcity"
    }
})
