/*
 * Copyright 2003-2014 the original author or authors.
 *
 * 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.
 */

import groovy.text.markup.MarkupTemplateEngine
import groovy.text.markup.TemplateConfiguration

buildscript {
    // this block should not be necessary, but for some reason it fails without!
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'me.champeau.gradle:japicmp-gradle-plugin:0.1.0'
    }
}

task checkBinaryCompatibility {
    description = 'Generates binary compatibility reports'
}
check.dependsOn(checkBinaryCompatibility)

if (JavaVersion.current().isJava7Compatible()) {
    apply plugin: 'me.champeau.gradle.japicmp'

    def referenceMinorVersion = '2.3.6'

    def reportGenerator = { model ->
        outputProcessor {

            def skipClass = { c ->
                c.fullyQualifiedName.startsWith('org.codehaus.groovy.runtime.dgm$') ||
                        c.fullyQualifiedName.contains('_closure')
            }
            def skipMethod = { c, m -> skipClass(c) || m.name =~ /access\$[0-9]+/ }
            def violations = [:].withDefault {
                // key = class name
                // value = map of violations
                [:].withDefault { [] }
            }
            removedMethod { c, m ->
                if (!skipMethod(c, m)) {
                    def level = m.name.startsWith('super$') ? 'warning' : 'error'
                    violations[c.fullyQualifiedName][level] << "Method ${m.name} has been removed"
                }
            }
            removedClass { c ->
                if (!skipClass(c)) {
                    violations[c.fullyQualifiedName].error << "Class has been removed"
                }
            }

            modifiedMethod { c, m ->
                if (!skipMethod(c, m)) {
                    violations[c.fullyQualifiedName].warning << """<p>Method ${m.name} has been modified</p>
<p>From <pre>${m.oldMethod.get()?.longName}</pre> to <pre>${m.newMethod.get()?.longName}</pre></p>"""
                }
            }

            newClass { c ->
                if (!skipClass(c)) {
                    violations[c.fullyQualifiedName].info << "Class has been added"
                }
            }
            newMethod { c, m ->
                if (!skipMethod(c, m)) {
                    violations[c.fullyQualifiedName].info << """<p>Method ${m.name} has been added</p>
<p>Signature: <pre>${m.newMethod.get()?.longName}</pre></p>"""
                }
            }
            after {
                model.violations = violations
            }
        }
    }

// using a global engine for all tasks in order to increase performance
    def configDir = file("$rootProject.projectDir/config/binarycompatibility")
    def templateFile = 'binarycompat-report.groovy'
    def templateConfiguration = new TemplateConfiguration()
    templateConfiguration.with {
        autoIndent = true
        autoNewLine = true
    }
    def engine = new MarkupTemplateEngine(this.class.classLoader, configDir, templateConfiguration)


    allprojects {

        task japicmp(type: me.champeau.gradle.ArtifactJapicmpTask) {
            dependsOn jarjar
            baseline = "org.codehaus.groovy:${project.name}:${referenceMinorVersion}@jar"
            to = jarjar.archivePath
            accessModifier = 'protected'
            onlyModified = true
            failOnModification = false
            txtOutputFile = file("$buildDir/reports/japi.txt")

            def htmlReportFile = file("${buildDir}/reports/binary-compat-${project.name}.html")
            inputs.file file("$configDir/$templateFile")
            inputs.file templateFile
            outputs.file htmlReportFile

            def model = [title   : "Binary compatibility report for ${project.name}",
                         project : project,
                         baseline: baseline,
                         archive : to.name]
            outputProcessor(reportGenerator.curry(model))

            doLast {
                htmlReportFile.withWriter('utf-8') { wrt ->
                    engine.createTemplateByPath(templateFile).make(model).writeTo(wrt)
                }
            }

        }
    }

    task japicmpAll(type: me.champeau.gradle.ArtifactJapicmpTask) {
        dependsOn jarAll
        baseline = "org.codehaus.groovy:groovy-all:${referenceMinorVersion}@jar"
        to = jarAll.archivePath
        accessModifier = 'protected'
        onlyModified = true
        failOnModification = false
        txtOutputFile = file("$buildDir/reports/japi.txt")

        def htmlReportFile = file("${buildDir}/reports/binary-compat-${project.name}-all.html")
        inputs.file file("$configDir/$templateFile")
        inputs.file templateFile
        outputs.file htmlReportFile

        def model = [title   : "Binary compatibility report for ${project.name}",
                     project : project,
                     baseline: baseline,
                     archive : to.name]
        outputProcessor(reportGenerator.curry(model))

        doLast {
            htmlReportFile.withWriter('utf-8') { wrt ->
                engine.createTemplateByPath(templateFile).make(model).writeTo(wrt)
            }
        }
    }


    allprojects {
        tasks.withType(me.champeau.gradle.ArtifactJapicmpTask) { task ->
            checkBinaryCompatibility.dependsOn(task)
        }
    }
}