#!/usr/bin/groovy
/*
 * #%L
 * Fuse EAP :: Testsuite :: Standalone
 * %%
 * Copyright (C) 2015 RedHat
 * %%
 * Licensed 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.
 * #L%
 */
import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode(excludes = "resources,path")
class Module {
    String name
    String slot
    String path
    def resources = []

    /**
     * Checks whether a module is associated with a particular artifact which matches a set of search parameters
     * @param resource The artifact to search for
     * @return True if a matching resource was found, false if not
     */
    def hasResource(def resource) {
        resources.contains(resource)
    }

    @Override
    public String toString() {
        "${name}:${slot}"
    }
}

def modulePath = "${properties.get("jboss.home")}/modules"
def modules = []
def duplicateResources = []
def problems = []

// Build up a list of modules and identify duplicates
new File(modulePath).eachFileRecurse() { file ->
    if (file.name.equals("module.xml") && !file.path.contains("layers/base")) {
        module = new Module()
        moduleXml = new XmlParser().parseText(file.getText())

        moduleXml.resources."resource-root".@path.each { resource ->
            module.resources << resource
        }

        module.name = moduleXml.attribute("name")
        module.slot = moduleXml.attribute("slot") ?: "main"
        module.path = "modules${file.parent.replace(modulePath, "")}"

        if (modules.contains(module)) {
            otherModule = modules.find { it.equals(module) }
            problems << "Duplicate module name and slot detected: ${module.name}:${module.slot}\n\t${module.path}\n\t${otherModule.path}\n"
        } else {
            modules << module
        }
    }
}

// Search for duplicated module resources
modules.each { module ->
    modules.each { otherModule ->
        if (!module.equals(otherModule)) {
            module.resources.each { resource ->
                if (otherModule.hasResource(resource) && !duplicateResources.contains("${module.path}/${resource}")) {
                    duplicateResources << "${otherModule.path}/${resource}"
                    problems << "Duplicate dependency ${resource}\n\t${module.path}/${resource}\n\t${otherModule.path}/${resource}\n"
                }
            }
        }
    }
}

// Output detected problems
if (problems.size() > 0) {
    println ""
    println "MODULE DEPENDENCY ERRORS DETECTED!!"
    println ""

    problems.each { problem ->
        println problem
    }

    if(Boolean.parseBoolean(properties.get("failonerror")).equals(Boolean.TRUE)) {
        println "Module dependency conflicts were detected"
        fail()
    }
}
