def call(Map args, Closure steps) {
    assert args.secrets: 'secrets is a required argument'
    assert args.secrets.getClass() in Collection: 'secrets must be a list or set of secrets'
    assert args.secrets.every{ it.id && it.environmentVariable }: 'each secret must specify id and environmentVariable'
    assert (!args.awsAccountId || args.awsRole): 'If awsAccountId is provided then awsRole must also be provided.'
    assert (!args.awsRole || args.awsAccountId): 'If awsRole is provided then awsAccountId must also be provided.'

    def environmentVariablesToSecretValues

    if (args.awsAccountId && args.awsRole) {
        withAWS(roleAccount: args.awsAccountId, role: args.awsRole, roleSessionName: env.BUILD_TAG, useNode: true) {
            environmentVariablesToSecretValues = getSecretValues(args.secrets)
        }
    }
    else {
        environmentVariablesToSecretValues = getSecretValues(args.secrets)
    }

    withEnv(environmentVariablesToSecretValues.collect{ "${it.key}=${it.value}" }) {
        maskPasswords(varPasswordPairs: environmentVariablesToSecretValues.collect{ [password: it.value] }) {
            steps()
        }
    }
}

def getSecretValues(def secrets) {
    def environmentVariablesToSecretValues = [:]
    def utils = new com.sonymusic.Utils(this)

    secrets.each {
        def region = it.region ?: 'us-east-1'
        def secretValue = utils.getSecretValue(it.id, region)
        environmentVariablesToSecretValues << [(it.environmentVariable): secretValue]
    }

    return environmentVariablesToSecretValues
}
