buildscript {
    repositories {
        mavenLocal()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
        dependencies {
            classpath "gradle.plugin.org.eclipse.virgo.bundlor:bundlor-plugin:0.2"
        }
    }
}

def timestamp = new Date().format('yyyyMMddHHmmss', TimeZone.getTimeZone('GMT'))

defaultTasks 'clean', 'build', 'snapsDist'

ext.planProjects = [
	project(':org.eclipse.virgo.snaps')
]

ext.bundleProjects = [    
    project(':org.eclipse.virgo.snaps.api'),
    project(':org.eclipse.virgo.snaps.core')
]

ext.testProjects = [    
    project(':org.eclipse.virgo.snaps.test')
]

allprojects {
    apply plugin: 'base'
    if (System.properties['ci.build'] == 'true') {
        def buildQualifier = System.properties['ci.build.qualifier']
        if(buildQualifier) { 
            version = version + '.' + buildQualifier
        } else {
            version = version + '.' + timestamp
        }
    } else {
        version = version + '.SNAPSHOT'
    }
}

configure(bundleProjects + testProjects + planProjects) {
    apply plugin: 'java'
    apply plugin: 'jacoco'
    apply plugin: 'findbugs'

    sourceCompatibility = '1.8'
    targetCompatibility = '1.8'

    compileJava {
        options.encoding = 'UTF-8'
        options.fork = true
        doFirst {
            options.forkOptions.with {
                executable = 'java'
                jvmArgs = [
                    '-cp',
                    configurations.ecj.asPath,
                    'org.eclipse.jdt.internal.compiler.batch.Main']
            }
        }
    }
    compileTestJava {
        options.encoding = 'UTF-8'
        options.fork = true
        doFirst {
            options.forkOptions.with {
                executable = 'java'
                jvmArgs = [
                    '-cp',
                    configurations.ecj.asPath,
                    'org.eclipse.jdt.internal.compiler.batch.Main']
            }
        }
    }
    repositories {
		mavenCentral()
		ivy {
			url "http://build.eclipse.org/rt/virgo/ivy/bundles/release/"
			layout "pattern", { artifact "[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" }
		}        
        maven{
            url "http://build.eclipse.org/rt/virgo/gradle/bundles/"
        }
	}
    configurations {
    	ecj {}
		testBundles {
			transitive = false
		}
	}
	// this is necessary because Gemini Web contains a dependency with wrong groupId/version combination 
	configurations.all {
		resolutionStrategy {
			dependencySubstitution {
				substitute module('javax.servlet:javax.servlet:3.0.0.v201103241009') with module('org.eclipse.virgo.mirrored:javax.servlet:3.0.0.v201103241009')  
			}
		}
	}
    jar {
    	// add SUA to archive
        from "$rootDir/build-bundlor/resources/about/notice.html"
		duplicatesStrategy 'exclude'
    }
    jar.doLast {
    	// signing the archives
        if(System.properties['ci.build.signjars'] == 'true') {
            println '|--> Signing Jar File: ' + archivePath
            exec {
                workingDir destinationDir
                commandLine 'curl',
                            '-o',
                            archiveName,
                            '-F',
                            "file=@${archiveName}",
                            '--show-error',
                            'http://build.eclipse.org:31338/sign'
            }
        }
    }
    jacoco {
        toolVersion = "0.7.4.201502262128"
    }
    findbugs {
        sourceSets = [sourceSets.main]
        ignoreFailures = true
        effort = "max"
        reportLevel = "high"
    }
    javadoc {
        failOnError = false
    }
    task sourcesJar(type: Jar, dependsOn: classes) {
    	description 'Assembles a jar archive containing the sources.'
    	group = 'build'
	    classifier = 'sources'
    	from sourceSets.main.allSource
	}
	task javadocJar(type: Jar, dependsOn: javadoc) {
	    description 'Assembles a jar archive containing the javadocs.'
    	group = 'build'
	    classifier = 'javadoc'
	    from javadoc.destinationDir
	}    	
}

configure(bundleProjects) {
    apply plugin: 'org.eclipse.virgo.bundlor'
	
	task('addProjectVersionToGradlePropertiesTask', type: Copy) {
		ext.outputDir = new File(buildDir, 'bundlor-properties')
		inputs.file project.rootProject.file('gradle.properties')
		outputs.dir ext.outputDir
		from project.rootProject.file('gradle.properties')
		into ext.outputDir
		doLast {
			def gradleProperties = new Properties()
			gradleProperties.load(new FileReader("${buildDir}/bundlor-properties/gradle.properties"))
			gradleProperties.setProperty('bundleName', "${archivesBaseName}")
			gradleProperties.setProperty('timestamp', "${timestamp}")
			gradleProperties.setProperty('version', "${version}")
			def writer = new FileWriter("${buildDir}/bundlor-properties/gradle.properties")
   			try {
      			gradleProperties.store(writer, 'modified during build process')
      			writer.flush()
   			} finally {
      			writer.close()
   			}
		}
	}
	task('mergeClassesAndResources', type: Copy, dependsOn: 'compileJava') {
		ext.bundlorInputPath = new File(buildDir, 'bundlor-inputPath')
		inputs.file sourceSets.main.output.classesDir
		inputs.file sourceSets.main.resources
		outputs.dir ext.bundlorInputPath
		from sourceSets.main.output.classesDir
		from sourceSets.main.resources
		into ext.bundlorInputPath
	}
	project.tasks.'bundlor'.dependsOn('addProjectVersionToGradlePropertiesTask', 'mergeClassesAndResources')
    bundlor {
    	ext.bundlorInputPath = new File(buildDir, 'bundlor-inputPath')
		project.tasks['bundlor'].inputs.file ext.bundlorInputPath
        manifestTemplatePath = "template.mf"
        propertiesPath = new File("${project.buildDir}/bundlor-properties/gradle.properties")
		inputPath = ext.bundlorInputPath
        failOnWarnings = true
    }
}

configure(bundleProjects + testProjects + planProjects) {
    apply plugin: 'eclipse'

    eclipse {
        jdt {
            sourceCompatibility = 1.8
            targetCompatibility = 1.8            
        }
        project {
            file.beforeMerged {
                project.natures.clear()
            }
            natures = ['org.eclipse.buildship.core.gradleprojectnature']
        }
    }
    cleanEclipse.doLast {
        delete '.settings'
        delete 'bin'
        delete '.springBeans'
    }
}

configure(bundleProjects) {
	apply plugin: 'maven-publish'
    publishing {
    	repositories {
        	maven {
                name = "BuildEclipseOrg"
                url "/opt/public/rt/virgo/gradle/bundles"
            }
        }
        publications {
            snaps(MavenPublication) {
                groupId 'org.eclipse.virgo.snaps'
                from components.java
            }
        }
    }
}

task snapsDist(type: Zip) {
    description 'Build Snaps distribution Zip file'
    group = 'distribution'
    
	archiveName "snaps-${version}.zip"
    duplicatesStrategy 'exclude'
    into("snaps-${version}/dist") {
        from 'org.eclipse.virgo.snaps/src/main/resources/'
        from bundleProjects.jar
    }
    into("snaps-${version}") {
    	from "build-snaps/resources"        
    }
}

task wrapper(type: Wrapper) {
    description 'Creates a local Gradle Wrapper'
    group = 'Build Setup'
    gradleVersion = '3.1'
}
