repositories {
    ivy {
        url "file://${projectDir}/repo"
    }
}

// Set up the status scheme so that "experimental" is a valid status for "org.sample" artifacts

class StatusRule implements ComponentMetadataRule {

    @Override
    void execute(ComponentMetadataContext componentMetadataContext) {
        def details = componentMetadataContext.details
        if (details.id.group == "org.sample") {
            details.statusScheme = ["experimental", "integration", "milestone", "release"]
        }
    }
}
dependencies {
    components {
        all(StatusRule)
    }
}

configurations {
    rejectConfig {
        resolutionStrategy {
            componentSelection {
                // Accept the highest version matching the requested version that isn't '1.5'
                all { ComponentSelection selection ->
                    if (selection.candidate.group == 'org.sample' && selection.candidate.module == 'api' && selection.candidate.version == '1.5') {
                        selection.reject("version 1.5 is broken for 'org.sample:api'")
                    }
                }
            }
        }
    }
}

dependencies {
    rejectConfig "org.sample:api:1.+"
}

task printRejectConfig {
    doLast {
        configurations.rejectConfig.each { println "Resolved: ${it.name}" }
    }
}

configurations {
    metadataRulesConfig {
        resolutionStrategy {
            componentSelection {
                // Reject any versions with a status of 'experimental'
                all { ComponentSelection selection, ComponentMetadata metadata ->
                    if (selection.candidate.group == 'org.sample' && metadata.status == 'experimental') {
                        selection.reject("don't use experimental candidates from 'org.sample'")
                    }
                }
                // Accept the highest version with either a "release" branch or a status of 'milestone'
                withModule('org.sample:api') { ComponentSelection selection, IvyModuleDescriptor descriptor, ComponentMetadata metadata ->
                    if (descriptor.branch != "release" && metadata.status != 'milestone') {
                        selection.reject("'org.sample:api' must have testing branch or milestone status")
                    }
                }
            }
        }
    }
}

dependencies {
    metadataRulesConfig "org.sample:api:1.+"
    metadataRulesConfig "org.sample:lib:+"
}

task printMetadataRulesConfig {
    doLast {
        configurations.metadataRulesConfig.each { println "Resolved: ${it.name}" }
    }
}

configurations {
    targetConfig {
        resolutionStrategy {
            componentSelection {
                withModule("org.sample:api") { ComponentSelection selection ->
                    if (selection.candidate.version == "1.5") {
                        selection.reject("version 1.5 is broken for 'org.sample:api'")
                    }
                }
            }
        }
    }
}

dependencies {
    targetConfig "org.sample:api:1.+"
}

task printTargetConfig {
    doLast {
        configurations.targetConfig.each { println "Resolved: ${it.name}" }
    }
}

class RejectTestBranch {
    @Mutate
    void evaluateRule(ComponentSelection selection, IvyModuleDescriptor ivy) {
        if (ivy.branch == "test") {
            selection.reject("reject test branch")
        }
    }
}

configurations {
    ruleSourceConfig {
        resolutionStrategy {
            componentSelection {
                all new RejectTestBranch()
            }
        }
    }
}

dependencies {
    ruleSourceConfig "org.sample:api:1.+"
}

task printRuleSourceConfig {
    doLast {
        configurations.ruleSourceConfig.each { println "Resolved: ${it.name}" }
    }
}

configurations {
    sampleConfig {
        resolutionStrategy {
            componentSelection {
                withModule("org.sample:api") { ComponentSelection selection ->
                    // Veto everything except patch releases
                    if (selection.candidate.version.matches('\\d+.\\d+\\.\\d+')) {
                        logger.lifecycle("** Accepted version: ${selection.candidate.version} **")
                    } else {
                        logger.lifecycle("Rejected version: ${selection.candidate.version}")
                        selection.reject("Version is broken")
                    }
                }
            }
        }
    }
}

dependencies {
    sampleConfig group: 'org.sample', name: 'api', version: '1+'
}

task resolveConfiguration {
    doLast {
        configurations.sampleConfig.each { println it }
    }
}
