/*
 * 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.
 */

/**
 * Gradle script used to perform DM releases (really similar to Apache ACE build.xml)
 */
import aQute.bnd.build.Workspace

buildscript {
  repositories {
    mavenCentral()
  }

  dependencies {
    classpath bnd_plugin
  }
}

// Our release number, which has to be monotonically incremented each time we make a new release.
ext.dmRelease = "r17"

// Our Apache svn Staging repo
ext.svnStagingPath = "https://dist.apache.org/repos/dist/dev/felix"

// Our Apache svn Release repo
ext.svnReleasePath = "https://dist.apache.org/repos/dist/release/felix"

apply plugin: 'java'
apply from: file("rat.gradle")

// Add bnd as a build dependency
buildscript {
    dependencies {
        classpath files('cnf/gradle/biz.aQute.bnd.gradle.jar')
    }
}

// Configure RAT plugin to ignore some files
rat {
  excludes = [
    'rat-report.xml',
    '**/.git/**',
    '**/.gradle/**',
    '**/.project',
    '**/.settings/**',
    '**/*.iml',
    '**/*.iws',
    '**/*.ipr',
    '**/.classpath',
    'cnf/**',
    'gradle/wrapper/**',
    'release/**',
    'gradlew',
    'README',
    '**/DEPENDENCIES',
    '**/README',
    '**/.gitignore',
    '**/generated/**',
    'doc/**',
    '**/packageinfo',
    '**/*.txt',
    'docs/**',
    '.metadata/**'
  ]
}

// Setup the workspace
Workspace workspace
workspace = Workspace.getWorkspace(".")

task makeStaging {
    doLast {
    description = 'Packages the source and binary distributions.'

    // Package source distributions.
    logger.lifecycle("    Packaging source distributions.")
    def topdir="org.apache.felix.dependencymanager-" + dmRelease
    ant.zip(destfile: "staging/"+topdir+'-src.zip') {
		zipfileset(dir: '../cnf', prefix: topdir+"-src/cnf", includes: ".project,.classpath,src/**,*.bnd,*.mvn,ext/**")
		zipfileset(dir: '..', prefix: topdir+"-src", includes: '*.gradle,*.properties')
		zipfileset(dir: 'resources/src', prefix: topdir+"-src", includes: '*')
		ant.zipfileset(dir: '..', prefix: topdir+"-src", includes: 'gradlew')
		ant.zipfileset(dir: '..', prefix: topdir+"-src", includes: 'changelog.txt')
    		ant.zipfileset(dir: '../.gradle-wrapper', prefix: topdir+"-src/.gradle-wrapper", includes: 'gradle-wrapper.properties')
		new File('.').eachFile { 
	    	    if(new File(it, 'bnd.bnd').exists()) {	    		
    			def bndProject = workspace.getProject(it.name)
    			if (! bndProject.isNoBundles() && ! bndProject.getName().endsWith(".benchmark")) {
    		    	    zipfileset(dir: "../${bndProject.name}", prefix: topdir+"-src/${bndProject.name}",
    			    	       includes: "*.gradle,.project,.classpath,.settings/**,src/**,test/**,*.bnd,*.bndrun,run-*/conf/**,resources/**,README*,changelog.txt")
    			}
	   	    }
		}
    }

    // Package binaries as a simple collection of bundles. We use same license files as for src distrib.
    logger.lifecycle("    Packaging binary distribution.")

    // First, get list of latest released bundles available from our Release repository
    def released = []
    def releaseRepo = workspace.getRepository("Release")
    def bundles=releaseRepo.list(null)
    bundles.each {
	    def sortedVersions = releaseRepo.versions(it)
	    def latestVersion = sortedVersions.last()
	    def latestBundle = releaseRepo.get(it, latestVersion, null)
	    released << latestBundle
    }

    // Before adding all latest released bundles in the binary distribution, check if they contain proper license files.
    logger.lifecycle("    Checking META-INF mandatory files.")
    released.each { jarfile -> 
    	if (jarfile.isFile()) {
       		new ByteArrayOutputStream().withStream { os ->
				def result = exec {
	    			executable = 'jar'
	    			args = ['tf', jarfile, "META-INF"]
	    			standardOutput = os
				}
				def files = os.toString().split("\n")
				def mandatory = ["META-INF/LICENSE", "META-INF/NOTICE", "META-INF/DEPENDENCIES", "META-INF/changelog.txt"]
				mandatory.each { resource ->			
					if (! files.contains(resource)) {
						throw new GradleException("Missing mandatory license files in " + jarfile)
					}
				}
			}
		}
    }

    // Now, add all the latest released bundles in the binary distribution
    ant.zip(destfile: "staging/"+topdir+"-bin.zip") {
        // include workspace changelog
	zipfileset(dir: '..', prefix: topdir+"-bin/", includes: "changelog.txt")

        // simply include all released bundle.
        released.each {
	    file=it
            ant.mappedresources() {
        	ant.filelist(files: file)
                ant.chainedmapper() {
                    ant.flattenmapper()
                    ant.globmapper(from: '*', to: topdir+'-bin/*')
                }
            }
        }
        ant.mappedresources() {
            ant.fileset(dir: 'resources/bin', includes: '*')
            ant.chainedmapper() {
                ant.flattenmapper()
                ant.globmapper(from: '*', to: topdir+'-bin/*')
            }
        }
    }
    }
}


 

// Sign staging directory (you must use "--no-daemon" gradle option)
task signStaging {
  doLast {
    	ant.input(message: 'Enter PGP password:', addproperty: 'pass')

        description = 'Signs the local staging distribution.'
	fileTree("staging").visit { FileVisitDetails details -> 
		logger.lifecycle("    Signing " + details.file.path)
		ant.exec(executable: 'gpg', dir: 'staging') {
			ant.arg(line: '--batch')
			ant.arg(line: '--passphrase')
			ant.arg(line: ant.properties.pass)
	    		ant.arg(line: '--armor')
	    		ant.arg(line: '--output')
	    		ant.arg(line: details.file.name + ".asc")
	    		ant.arg(line: "--detach-sig")
	    		ant.arg(line: details.file.name)
		}

		ant.exec(executable: 'gpg', dir: 'staging', output: "staging/" + details.file.name + ".sha1") {
	    		ant.arg(line: '--print-md')
	    		ant.arg(line: 'SHA1')
	    		ant.arg(line: details.file.name)
		}

		ant.exec(executable: 'gpg', dir: 'staging', output: "staging/" + details.file.name + ".sha512") {
	    		ant.arg(line: '--print-md')
	    		ant.arg(line: 'SHA512')
	    		ant.arg(line: details.file.name)
		}
	}
    }
}



// Moves the source and binary distributions to staging.
task commitToStaging {
  doLast {
    description = 'Commits the local staging to the Apache svn staging repository.'
    ant.input(message: 'Enter SVN user:', addproperty: 'user')
    ant.input(message: 'Enter SVN password:', addproperty: 'password')
    def user = ant.properties.user
    def password = ant.properties.password

    getProject().exec {
    	commandLine 'svn', 
		'import', 'staging', svnStagingPath + "/org.apache.felix.dependencymanager-" + dmRelease + "/", 
		'-m', "Staging Apache Felix Dependency Manager release " + dmRelease + ".", "--username", user, "--password", password
    }
  }
}

// Promotes the staged distributions to release
task promoteToRelease {
  doLast {
    description = 'Moves the staging repository to the Apache release repository.'
    ant.input(message: 'Enter SVN user:', addproperty: 'user')
    ant.input(message: 'Enter SVN password:', addproperty: 'password')
    def user = ant.properties.user
    def password = ant.properties.password

    // Move all artifacts from the staging repo to the release repo
    new ByteArrayOutputStream().withStream { os ->
		def result = exec {
	    	executable = 'svn'
	    	args = ['list', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease]
	    	standardOutput = os
		}
		def outputAsString = os.toString()

		outputAsString.split("\n").each { artifact -> 
	    	logger.lifecycle("    Moving " + artifact + " to release repository ...")
	    	getProject().exec { 
				commandLine 'svn',
				'move', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease + "/" + artifact , 
				svnReleasePath, '-m', "Releasing Apache Felix Dependency Manager release " + dmRelease + ".",
				"--username", user, "--password", password
	    	}
		}
    }

    // And remove the toplevel release path from the staging repo
    logger.lifecycle("    Removing org.apache.felix.dependencymanager-" + dmRelease + " from staging ...")    
    getProject().exec { 
    	commandLine 'svn',
		'rm', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease, "-m", 
		"Releasing Apache Felix Dependency Manager release " + dmRelease + ".",
		"--username", user, "--password", password
    }
  }
}

// Removes the staged distributions from staging
task deleteFromStaging {
  doLast {
    description = 'Cancels the staged distribution from the Apache staging repository.'
    ant.input(message: 'Enter SVN user:', addproperty: 'user')
    ant.input(message: 'Enter SVN password:', addproperty: 'password')
    def user = ant.properties.user
    def password = ant.properties.password

    getProject().exec { 
    	commandLine 'svn',
		'delete', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease + "/",
		"-m", "Removing Apache Felix Dependency Manager release " + dmRelease + " from staging.",
		"--username", user, "--password", password		
    }
  }
}

// Clean staging directory

clean.doLast {
    new File("release/staging").deleteDir()
    new File("rat-report.xml").delete()
}

// Only clean the staging directory
task cleanStaging {
  doLast {
    description = 'Clean the local staging directory.'
    new File("release/staging").deleteDir()
    new File("release/staging-copy").deleteDir()
  }
}
