/*
 *  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.
 */
import groovy.text.markup.MarkupTemplateEngine
import groovy.text.markup.TemplateConfiguration

allprojects { proj ->
    apply plugin: "org.nosphere.apache.rat"
    //apply plugin: "com.github.hierynomus.license"
    apply plugin: 'checkstyle'
    apply plugin: 'codenarc'
    apply plugin: 'com.github.spotbugs'
    configurations.codenarc {
        // because we will rely on the version we build
        // because version ranges are evil
        // and because it causes bnd to be brought transitively
        // I am unsure why; says it is required by groovy-ant but its pom.xml does not declare so
        resolutionStrategy.dependencySubstitution {
            substitute module("org.codehaus.groovy:groovy") with project(":")
            substitute module("org.codehaus.groovy:groovy-ant") with project(":groovy-ant")
            substitute module("org.codehaus.groovy:groovy-xml") with project(":groovy-xml")
            substitute module("org.codehaus.groovy:groovy-json") with project(":groovy-json")
            substitute module("org.codehaus.groovy:groovy-groovydoc") with project(":groovy-groovydoc")
        }

        exclude module: 'groovy-all'
    }

    dependencies {
        checkstyle "com.puppycrawl.tools:checkstyle:$checkstyleVersion"
        codenarc "org.codenarc:CodeNarc:3.0.0"
        spotbugs "com.github.spotbugs:spotbugs:$spotbugsVersion"
        if (proj.name.contains('jaxb') && JavaVersion.current().isJava9Compatible()) {
            spotbugs 'javax.xml.bind:jaxb-api:2.3.0'
        }
        codenarc project(":groovy-templates")
    }

//    license {
//        header rootProject.file('config/licensing/HEADER.txt')
//        include "**/*.groovy"
//        include "**/*.java"
//        include "**/*.properties"
//        include "**/*.js"
//        include "**/*.css"
//        include "**/*.html"
//        include "**/*.gradle"
//        include "**/*.xml"
//        exclude "org/codehaus/groovy/antlr/**"
//        exclude 'reloading/**' // test resources for documentation of reloading
//        exclude 'includes/**' // documentation resources included as snippets of code
//        //dryRun = true
//        ignoreFailures = true
//        //skipExistingHeaders = true
//        //ext.year = Calendar.instance.get(Calendar.YEAR)
//    }

    // don't fail build on CodeNarc tasks
    tasks.withType(CodeNarc) {
        //dependsOn jar
        ignoreFailures = true
        configFile = file("$rootProject.projectDir/config/codenarc/codenarc.groovy")
//        doFirst {
//            configurations.codenarc.files.each { println it }
//        }
    }

    tasks.withType(Checkstyle) {
        showViolations = false
        ignoreFailures = true
        configFile = file("$rootProject.projectDir/config/checkstyle/checkstyle.xml")
        configProperties = ['rootProject.projectDir': rootProject.projectDir]
        def reportFile = file("${buildDir}/reports/checkstyle/${name}.xml")
        reports {
            include ( '**/*.java')
            xml {
                destination reportFile
            }
        }
        if (!source.empty) {
            task("${name}Report") {
                def configDir = file("$rootProject.projectDir/config/checkstyle")
                def templateFile = 'checkstyle-report.groovy'
                def htmlReportFile = file("${buildDir}/reports/checkstyle/${name}.html")
                inputs.file file("$configDir/$templateFile")
                inputs.file reportFile
                outputs.file htmlReportFile

                doLast {
                    def templateConfiguration = new TemplateConfiguration()
                    templateConfiguration.with {
                        autoIndent = true
                        autoNewLine = true
                    }
                    def engine = new MarkupTemplateEngine(this.class.classLoader, configDir, templateConfiguration)
                    def xml = new XmlSlurper().parse(reportFile.newReader('utf-8'))
                    def files = []
                    xml.file.each { f ->
                        if (f.error.size() && !f.@name.toString().matches('.*[/\\\\]generated[/\\\\].*')) {
                            files << [
                                    name: f.@name.toString(),
                                    errors: f.error.collect { e ->
                                        def rule = e.@source.toString()
                                        rule = rule.substring(rule.lastIndexOf('.')+1)
                                        [line: e.@line.toString(),
                                         column: e.@column.toString(),
                                         message: e.@message.toString(),
                                         source: rule,
                                         severity: e.@severity.toString()]
                                    }]
                        }
                    }
                    def model = [
                            project: project,
                            files: files
                    ]
                    htmlReportFile.withWriter('utf-8') { wrt ->
                        engine.createTemplateByPath('checkstyle-report.groovy').make(model).writeTo(wrt)
                    }
                }
            }
            finalizedBy "${name}Report"
        }
    }

    tasks.withType(SpotBugsTask) {
        // TODO work out why the following aren't being set automatically
        if (proj.name.contains('jaxb')) {
            reportsDir = file("$buildDir/reports/spotbugs")
            projectName = proj.name
            release = rootProject.version
        }
        excludeFilter = file("$rootProject.projectDir/config/spotbugs/exclude.xml")
        ignoreFailures = true
        effort = 'max'
        maxHeapSize = '2g'
        reports {
            xml.enabled = false
            html {
                enabled = true
                stylesheet = 'fancy.xsl'
            }
        }
    }
}

subprojects { sp ->
    def extras = []
    switch(sp.name) {
        case 'groovy-templates':
            extras = [
                    // test files
                    'src/spec/test-resources/*.txt',
                    'src/test/resources/includes/hello-escaped.txt',
                    'src/test/resources/includes/hello.html'
            ]
            break
        case ['groovy-groovydoc', 'groovy-docgenerator']:
            extras = [
                    '**/stylesheet.css'  // MIT license as per NOTICE/LICENSE files
            ]
            break
    }
    rat {
        inputDir = sp.projectDir
        excludes = [ 'target/**', 'build/**', '.gradle/**', '*.iml', '.classpath', '.project', '.settings/**', 'bin/**' , *extras]
    }
}

rat {
    inputDir = projectDir
    excludes = [ 'subprojects/**', // covered above
                 'benchmark/**', // benchmarking files excluded from src zip
                 'config/**',
                 'src/install/**', // CI file excluded from src zip
                 'src/test/org/codehaus/groovy/ast/LineColumnCheck.txt', // test file
                 'security/groovykeys', // excluded from src zip
                 '**/.gradle/**', '**/wrapper/**', 'gradlew*',  // gradle wrapper files excluded from src zip
                 'artifactory.properties',  // potential file on CI server
                 'gradle.properties',  // artifactory release plugin removes header when bumping version
                 '**/target/**', '**/build/**', 'licenses/**', 'notices/**',
                 'out/**', '*.ipr',  '**/*.iml', '*.iws', '.idea/**', // Intellij files
                 '**/style.css', // MIT license as per NOTICE/LICENSE files
                 '**/jquery-2.1.1.min.js', // MIT license as per NOTICE/LICENSE files
                 '.classpath', '.project', '.settings/**', 'bin/**', // Eclipse files
                 'bootstrap/settings.gradle', // empty file
                 '.jqwik-database'
    ]
}

apply from: 'gradle/jacoco/jacoco.gradle'

sonarqube {
    properties {
        property "sonar.projectName", "Apache Groovy"
        property "sonar.projectKey", "apache_groovy"
        property "sonar.organization", "apache"
        property "sonar.host.url", "https://sonarcloud.io"
//        property "sonar.coverage.jacoco.xmlReportPaths", "${rootProject.buildDir}/reports/jacoco/jacocoAllReport/jacocoAllReport.xml"
    }
}
