/*
 * 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 = "r13"

// 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*")
    			}
	   	    }
		}
    }

    // 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") {
        // 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.'
    getProject().exec { 
    	commandLine 'svn', 
		'import', 'staging', svnStagingPath + "/org.apache.felix.dependencymanager-" + dmRelease + "/", 
		'-m', "Staging Apache Felix Dependency Manager release " + dmRelease + ".", "--force-interactive"
    }
  }
}

// Promotes the staged distributions to release
task promoteToRelease {
  doLast {
    description = 'Moves the staging repository to the Apache release repository.'

    // 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 + "."
	    	}
		}
    }

    // 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 + "."
    }
  }
}

// Removes the staged distributions from staging
task deleteFromStaging {
  doLast {
    description = 'Cancels the staged distribution from the Apache staging repository.'
    getProject().exec { 
    	commandLine 'svn',
		'delete', svnStagingPath+"/org.apache.felix.dependencymanager-" + dmRelease + "/",
		"-m", "Removing Apache Felix Dependency Manager release " + dmRelease + " from staging."
    }
  }
}

// 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()
  }
}
