import java.nio.charset.StandardCharsets

def decode64(String varName) {
	String envValue = System.env[varName]
	if (envValue == null) {
		return ""
	} else {
		return new String(envValue.decodeBase64(), "UTF-8")
	}
}

if (project.parent == null) {
	group = 'com.diffplug.spotless'
	def pass = System.env['ORG_GRADLE_PROJECT_nexus_pass64']
	if (pass != null) {
		pass = pass.decodeBase64()
	}
	// it's the root project
	apply plugin: 'io.github.gradle-nexus.publish-plugin'
	nexusPublishing {
		repositories {
			sonatype {
				nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
				snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
				username = System.env['ORG_GRADLE_PROJECT_nexus_user']
				password = decode64('ORG_GRADLE_PROJECT_nexus_pass64')
			}
		}
	}
	def initTask = tasks.named('initializeSonatypeStagingRepository')
	allprojects {
		initTask.configure {
			shouldRunAfter(tasks.withType(Sign))
		}
	}
	return
}

///////////
// MAVEN //
///////////
java {
	withJavadocJar()
	withSourcesJar()
}

tasks.named('sourcesJar') {
	dependsOn 'jar'
}

apply plugin: 'maven-publish'
apply plugin: 'signing'

// Where it's possible to name parameters and methods clearly enough
// that javadoc is not necessary, why make the code bigger?
//
// Thus, no javadoc warnings.
javadoc {
	options.addStringOption('Xdoclint:none', '-quiet')
	options.addStringOption('Xwerror', '-quiet')
}
// make sure bad javadoc breaks the build
tasks.named('check') {
	dependsOn tasks.named('javadoc')
}

// use markdown in javadoc
def makeLink = { url, text -> "<a href=\"${url}\" style=\"text-transform: none;\">${text}</a>" }
def javadocInfo = '<h2>' + makeLink("https://github.com/${org}/${name}", "${group}:${project.ext.artifactId}:${version}") +
		' by ' + makeLink('https://www.diffplug.com', 'DiffPlug') + '</h2>'

String dotdotGradle = project.name.startsWith('eclipse-') ? '../../gradle' : '../gradle'
javadoc {
	options.encoding = 'UTF-8'
	// Where it's possible to name parameters and methods clearly enough
	// that javadoc is not necessary, why make the code bigger?
	//
	// Thus, no javadoc warnings.
	options.addStringOption('Xdoclint:none', '-quiet')
	options.addStringOption('source', '17')
	// setup the header
	options.header javadocInfo
	// setup links
	options.linksOffline('https://docs.gradle.org/6.1.1/javadoc/', "${dotdotGradle}/javadoc/gradle")

	// links to javadoc from the other versions
	options.linksOffline("https://javadoc.io/static/com.diffplug.spotless/spotless-lib/${rootProject.spotlessChangelog.versionLast}", "${dotdotGradle}/javadoc/spotless-lib")
	options.linksOffline("https://javadoc.io/static/com.diffplug.spotless/spotless-lib-extra/${rootProject.spotlessChangelog.versionLast}", "${dotdotGradle}/javadoc/spotless-lib-extra")
}

////////////////
// PUBLISHING //
////////////////
final MAVEN_PLUGIN_ARTIFACT_NAME = 'spotless-maven-plugin'
boolean isExt = project.name.startsWith('eclipse-')
boolean isPluginMaven = project.ext.artifactId == 'spotless-maven-plugin'

model {
	publishing {
		publications {
			pluginMaven(MavenPublication) {
				if (project.ext.artifactId != 'spotless-plugin-gradle') {
					from components.java
				}

				groupId = project.group
				artifactId = project.ext.artifactId
				version = project.version

				def projectExtArtifactId = project.ext.artifactId
				def projectDescription = project.description
				def projectOrg = project.org
				def rootProjectName = rootProject.name

				pom.withXml {
					// add MavenCentral requirements to the POM
					asNode().children().last() + {
						resolveStrategy = Closure.DELEGATE_FIRST
						name projectExtArtifactId
						description projectDescription
						url "https://github.com/${projectOrg}/${rootProjectName}"
						scm {
							url "https://github.com/${projectOrg}/${rootProjectName}"
							connection "scm:git:https://github.com/${projectOrg}/${rootProjectName}.git"
							developerConnection "scm:git:ssh:git@github.com/${projectOrg}/${rootProjectName}.git"
						}
						licenses {
							if (isExt) {
								license {
									name 'Eclipse Public License - v 1.0'
									url 'https://www.eclipse.org/legal/epl-v10.html'
									distribution 'repo'
								}
							} else {
								license {
									name 'The Apache Software License, Version 2.0'
									url 'https://www.apache.org/licenses/LICENSE-2.0.txt'
									distribution 'repo'
								}
							}
						}
						if (isPluginMaven) {
							// Maven plugin required Maven 3.1.0+ to run
							prerequisites { maven '3.1.0' }
						}
						developers {
							if (isExt) {
								project.ext.developers.each { extId, extValues ->
									developer {
										id extId
										name extValues['name']
										email extValues['email']
									}
								}
							} else {
								if (isPluginMaven) {
									developer {
										id 'lutovich'
										name 'Konstantin Lutovich'
										email 'konstantin.lutovich@neotechnology.com'
									}
								}
								developer {
									id 'nedtwigg'
									name 'Ned Twigg'
									email 'ned.twigg@diffplug.com'
								}
							}
						}
					}
				}
			}
		}
	}
}

if (System.env['JITPACK'] == 'true' || version.endsWith('-SNAPSHOT')) {
	signing {
		setRequired(false)
	}
} else {
	signing {
		String gpg_key = decode64('ORG_GRADLE_PROJECT_gpg_key64')
		useInMemoryPgpKeys('0x4272C851', gpg_key, System.env['ORG_GRADLE_PROJECT_gpg_passphrase'])
		sign(publishing.publications)
	}

	// find the project with the changelog (this project for plugins, root project for libs)
	def changelogTasks = (tasks.names.contains('changelogBump') ? project : rootProject).tasks

	// ensures that nothing will be built if changelogPush will end up failing
	tasks.named('jar').configure {
		dependsOn changelogTasks.named('changelogCheck')
	}
	// ensures that changelog bump and push only happens if the publish was successful
	def thisProj = project
	changelogTasks.named('changelogBump').configure {
		dependsOn ":${thisProj.path}:publishPluginMavenPublicationToSonatypeRepository"
		dependsOn ":closeAndReleaseSonatypeStagingRepository"
		// if we have a Gradle plugin, we need to push it up to the plugin portal too
		if (thisProj.tasks.names.contains('publishPlugins')) {
			dependsOn thisProj.tasks.named('publishPlugins')
		}
	}
}

tasks.withType(AbstractArchiveTask).configureEach {
	preserveFileTimestamps = false
	reproducibleFileOrder = true
}
