import org.gradle.plugins.signing.Sign

buildscript {
    repositories {
        jcenter()
        maven { url 'http://dl.bintray.com/content/aalmiray/kordamp' }
    }
    dependencies {
        classpath 'org.kordamp:markdown-gradle-plugin:0.1.1'
    }
}
apply plugin: 'org.kordamp.gradle.markdown'

allprojects {
	apply plugin: 'java'
	apply plugin: 'eclipse'

	ext {
		shortVersion = '4.1.0-alpha5'
		isSnapshot = true
		gitCommit = getGitCommit()
		javadocAllDir = new File(buildDir, 'javadoc')
		documentationDir = new File(buildDir, 'documentation')
		releasedocsDir = new File(buildDir, 'releasedocs')
		rootConfigDir = new File(rootDir, 'config')
		sonatypeCredentialsAvailable = project.hasProperty('sonatypeUsername') && project.hasProperty('sonatypePassword')
		isReleaseVersion = !isSnapshot
		signingRequired = isReleaseVersion
		sonatypeSnapshotUrl = 'https://oss.sonatype.org/content/repositories/snapshots'
		sonatypeStagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2'
		// Returns only the date in yyyy-MM-dd format, as otherwise, with
		// hh:mm:ss information, the manifest files would change with every
		// build, causing unnecessary rebuilds.
		builtDate = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date())
		oneLineDesc = 'An Open Source XMPP (Jabber) client library'
		jxmppVersion = "0.3.0"
		smackMinAndroidSdk = 8
		androidProjects = [':smack-tcp',':smack-core', ':smack-resolver-minidns', ':smack-sasl-provided', ':smack-extensions', ':smack-experimental'].collect{ project(it) }
		androidBootClasspath = getAndroidRuntimeJar()
		androidJavadocOffline = getAndroidJavadocOffline()
	}
	group = 'org.igniterealtime.smack'
	sourceCompatibility = 1.7
	targetCompatibility = sourceCompatibility
	version = shortVersion
	if (isSnapshot) {
		version += '-SNAPSHOT'
	}

	ext.sharedManifest = manifest {
		attributes('Implementation-Version': version,
				   'Implementation-GitRevision': ext.gitCommit,
				   // According to OSGi core 5.0 section 3.2.5 the qualifier (the fourth
				   // version element) must begin with a dot. So we replace only the
				   // first occurence of an dash with a dot.
				   // For example 4.0.0-rc1 becomes 4.0.0.rc1, but
				   // 4.0.0-SNAPSHOT-2014-05-01 becomes 4.0.0.SNAPSHOT-2014-05-01
				   'Bundle-Version': version.replaceFirst("-", "."),
				   'Built-Date': ext.builtDate,
				   'Built-JDK': System.getProperty('java.version'),
				   'Built-Gradle': gradle.gradleVersion,
				   'Built-By': System.getProperty('user.name')
				  )
	}

	eclipse {
		classpath {
			downloadJavadoc = true
		}
	}

	repositories {
		// Add OSS Sonatype Snapshot repository
		maven {
			url 'https://oss.sonatype.org/content/repositories/snapshots'
		}
	}

	compileJava {
		// Some systems may not have set their platform default
		// converter to 'utf8', but we use unicode in our source
		// files. Therefore ensure that javac uses unicode
		options.encoding = "utf8"
	}

	if (JavaVersion.current().isJava8Compatible()) {
		tasks.withType(Javadoc) {
			options.addStringOption('Xdoclint:none', '-quiet')
		}
	}
}

gradle.taskGraph.whenReady { taskGraph ->
	if (signingRequired
		&& taskGraph.allTasks.any { it instanceof Sign }) {
		// Use Java 6's console to read from the console (no good for a CI environment)
		Console console = System.console()
		console.printf '\n\nWe have to sign some things in this build.\n\nPlease enter your signing details.\n\n'
		def password = console.readPassword('GnuPG Private Key Password: ')

		allprojects { ext.'signing.password' = password }

		console.printf '\nThanks.\n\n'
	}
}

task javadocAll(type: Javadoc) {
	source subprojects.collect {project ->
		project.sourceSets.main.allJava }
	destinationDir = javadocAllDir
	// Might need a classpath
	classpath = files(subprojects.collect {project ->
		project.sourceSets.main.compileClasspath})
	options.linkSource = true
	options.use = true
	options.links = ["http://docs.oracle.com/javase/$sourceCompatibility/docs/api/"] as String[]
}

import org.apache.tools.ant.filters.ReplaceTokens
task prepareReleasedocs(type: Copy) {
	from 'resources/releasedocs'
	into releasedocsDir
	filter(ReplaceTokens, tokens: [version: version, releasedate: builtDate, targetCompatibility: targetCompatibility.toString()])
}

markdownToHtml {
	sourceDir = new File(projectDir, "/documentation")
	outputDir documentationDir
	configuration = [tables: true, fencedCodeBlocks: true]
}

task distributionZip(type: Zip, dependsOn: [javadocAll, prepareReleasedocs, markdownToHtml]) {
	classifier builtDate
	into ('javadoc') {
		from(javadocAllDir)
	}
	into ('releasedocs') {
		from(releasedocsDir)
	}
	into ('releasedocs/documentation') {
		from(documentationDir)
	}
}

task maybeCheckForSnapshotDependencies {
	// Don't check for Snapshot dependencies if this is a snapshot.
	if (isSnapshot) return
	allprojects { project ->
		project.configurations.runtime.each {
			if (it.toString().contains("-SNAPSHOT"))
				throw new Exception("Release build contains snapshot dependencies: " + it)
		}
	}
}

test { dependsOn maybeCheckForSnapshotDependencies }

jar {
	// Root project should not create empty jar artifact
	enabled = false
}

// Disable upload archives for the root project
uploadArchives.enabled = false

description = """\
Smack ${version}
${oneLineDesc}."""

evaluationDependsOnChildren()
subprojects {
	apply plugin: 'maven'
	apply plugin: 'osgi'
	apply plugin: 'signing'
	apply plugin: 'checkstyle'

	checkstyle {
		configFile = new File(rootConfigDir, 'checkstyle.xml')
	}
	repositories {
		mavenLocal()
		mavenCentral()
	}
	task sourcesJar(type: Jar, dependsOn: classes) {
		classifier = 'sources'
		from sourceSets.main.allSource
	}
	task javadocJar(type: Jar, dependsOn: javadoc) {
		classifier = 'javadoc'
		from javadoc.destinationDir
	}
	task testJar(type: Jar) {
		classifier = 'tests'
		from sourceSets.test.output
	}
	artifacts {
		archives sourcesJar
		archives javadocJar
		archives testJar
	}

	uploadArchives {
		repositories {
			mavenDeployer {
				if (signingRequired) {
					beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
				}
				repository(url: project.sonatypeStagingUrl) {
					if (sonatypeCredentialsAvailable) {
						authentication(userName: sonatypeUsername, password: sonatypePassword)
					}
				}
				snapshotRepository(url: project.sonatypeSnapshotUrl) {
					if (sonatypeCredentialsAvailable) {
						authentication(userName: sonatypeUsername, password: sonatypePassword)
					}
				}

				pom.project {
					name 'Smack'
					packaging 'jar'
					inceptionYear '2003'
					url 'http://www.igniterealtime.org/projects/smack/'
					description project.description

					issueManagement {
						system 'JIRA'
						url 'https://igniterealtime.org/issues/browse/SMACK'
					}

					distributionManagement {
						snapshotRepository {
							id 'smack.snapshot'
							url project.sonatypeSnapshotUrl
						}
					}

					scm {
						url 'https://github.com/igniterealtime/Smack'
						connection 'scm:git:https://github.com/igniterealtime/Smack.git'
						developerConnection 'scm:git:https://github.com/igniterealtime/Smack.git'
					}

					licenses {
						license {
							name 'The Apache Software License, Version 2.0'
							url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
							distribution 'repo'
						}
					}

					developers {
						developer {
							id 'flow'
							name 'Florian Schmaus'
							email 'flow@igniterealtime.org'
						}
					}
				}
			}
		}
	}
	rootProject.distributionZip {
		dependsOn build
		from(buildDir) {
			include "$libsDirName/*${version}.jar"
			include "$libsDirName/*${version}-javadoc.jar"
			include "$libsDirName/*${version}-sources.jar"
		}
	}
	signing {
		required { signingRequired }
		sign configurations.archives
	}
}

['smack-extensions', 'smack-experimental', 'smack-legacy'].each { name ->
	project(":$name") {
		jar {
			manifest {
				instruction 'Service-Component', "org.jivesoftware.smackx/$name-components.xml"
			}
		}
	}
}

['smack-resolver-javax', 'smack-resolver-dnsjava', 'smack-resolver-minidns', 'smack-sasl-javax', 'smack-sasl-provided', 'smack-java7'] .each { name ->
	project(":$name") {
		jar {
			manifest {
				instruction 'Service-Component', "org.jivesoftware.smack/$name-components.xml"
			}
		}
	}
}

subprojects*.jar {
   manifest {
       from sharedManifest
   }
}

def getGitCommit() {
	def dotGit = new File("$projectDir/.git")
	if (!dotGit.isDirectory()) return 'non-git build'

	def cmd = 'git describe --always --tags --dirty=+'
	def proc = cmd.execute()
	def gitCommit = proc.text.trim()
	assert !gitCommit.isEmpty()
	gitCommit
}

def getAndroidRuntimeJar() {
	def androidHome = getAndroidHome()
	def androidJar = new File("$androidHome/platforms/android-$smackMinAndroidSdk/android.jar")
	if (androidJar.isFile()) {
		return androidJar
	} else {
		throw new Exception("Can't find android.jar for $smackMinAndroidSdk API. Please install corresponding SDK platform package")
	}
}

def getAndroidJavadocOffline() {
	def androidHome = getAndroidHome()
	return androidHome.toString() + "/docs/reference"
}

def getAndroidHome() {
	def androidHomeEnv = System.getenv("ANDROID_HOME")
	if (androidHomeEnv == null) {
		throw new Exception("ANDROID_HOME environment variable is not set")
	}
	def androidHome = new File(androidHomeEnv)
	if (!androidHome.isDirectory()) throw new Exception("Environment variable ANDROID_HOME is not pointing to a directory")
	return androidHome
}
