package twitch.instrumentorum.project.features

import jetbrains.buildServer.configs.kotlin.v2018_2.ErrorConsumer
import jetbrains.buildServer.configs.kotlin.v2018_2.ProjectFeature
import jetbrains.buildServer.configs.kotlin.v2018_2.ProjectFeatures
import twitch.instrumentorum.enums.AWSRegion

/**
 *
 */
open class ECRConnection() : ProjectFeature() {
    /**
     * ECR connection display name
     */
    var name by stringParameter("displayName")

    /**
     * Should we use the default credential provider chain?
     */
    var useCredentialChain by booleanParameter("aws.use.default.credential.provider.chain", "true", "")

    /**
     * AWS region of the ecr repo, like 'us-west-2'
     */
    var region by enumParameter<AWSRegion>("aws.region.name")

    /**
     * AWS account ID for the repository
     */
    var accountId by stringParameter("registryId")

    /**
     * Role to assume for cross account access
     */
    var assumeRole by stringParameter("aws.iam.role.arn")

    init {
        type = "OAuthProvider"

        // defaults
        name = "Amazon ECR"
        useCredentialChain = true
        region = AWSRegion.PDX
        accountId = "994136867826"

        // unexposed parameters
        param("providerType", "AmazonDocker")
        param("aws.credentials.type", "aws.access.keys")
    }

    constructor(init: ECRConnection.() -> Unit) : this() {
        init()
    }

    override fun validate(consumer: ErrorConsumer) {
        super.validate(consumer)

        val role = assumeRole ?: ""
        val account = accountId ?: ""

        if (!account.matches("^[0-9]{12}$".toRegex())) {
            val message = "mandatory 'accountId' property must be a 12 digit numerical value"
            consumer.consumePropertyError("ecrAccountId", message)
        }

        if (role.isBlank()) {
            assumeRole = null
            return
        }

        param("aws.credentials.type", "aws.temp.credentials")

        if (role.matches("^[\\w-]+$".toRegex())) {
            assumeRole = "arn:aws:iam::$account:role/$role"
        } else if (!role.matches("^arn:aws:iam::$account:role/[\\w-]+$".toRegex())) {
            val message = "when providing a full arn to `assumeRole` it must match the `accountId` property"
            consumer.consumePropertyError("assumeRole", message)
        }
    }
}

/**
 * @see ECRConnection
 */
fun ProjectFeatures.ecrConnection(init: ECRConnection.() -> Unit): ECRConnection {
    val result = ECRConnection(init)
    feature(result)
    return result
}
