/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */

// Check if dependency resolution is happening at configuration time
def resolvingAllowed = false
int pcount = allprojects.size()
allprojects { p ->
    p.afterEvaluate {
        resolvingAllowed = --pcount == 0
    }
    def checkResolution = { cnf ->
        cnf.incoming.beforeResolve {
            if (!resolvingAllowed) {
                def e = new RuntimeException()
                List<StackTraceElement> inGradleBuild = e.stackTrace.findAll { it.fileName?.endsWith('.gradle') && !it.fileName.endsWith('bad-practices.gradle') }
                def stack = inGradleBuild.collect {
                    "   at ${it.fileName}:${it.lineNumber}"
                }.join("\n")
                throw new IllegalStateException("Configuration $cnf in project $p is being resolved at configuration time.\nThis shouldn't be necessary and usually indicates an error in the build script.\nSee :\n${stack}")
            }
        }
    }
    p.configurations.all(checkResolution)
    // This will make sure we also capture problems with detached configurations
    // However it will only do so with build scripts that use dynamic Groovy
    p.configurations.metaClass = new ContainerMetaclassClass(p.configurations.metaClass, checkResolution)
}

@groovy.transform.CompileStatic
class ContainerMetaclassClass extends DelegatingMetaClass {
    Closure configuration

    ContainerMetaclassClass(MetaClass metaClass, Closure configuration) {
        super(metaClass)
        this.configuration = configuration
    }

    Object invokeMethod(Object object, String name, Object[] args) {
        maybeConfigure(super.invokeMethod(object, name, args), name)
    }

    Object invokeMethod(Object object, String name, Object arg) {
        maybeConfigure(super.invokeMethod(object, name, arg), name)
    }
    
    private Object maybeConfigure(Object object, String name) {
        if ('detachedConfiguration' == name) {
            configuration(object)
        }
        object
    }
}
