
/**
 * This task should be used to easily bump the major/minor/patch version of a fabric-api module.
 * It will automatically bump the versions of dependent modules.
 */
tasks.register('bumpVersions', BumpVersionTask)

class BumpVersionTask extends DefaultTask {
	BumpVersionTask() {
		group = "publishing"

		outputs.upToDateWhen { false }
	}

	@TaskAction
	void runTask() {
		def scanner = new Scanner(System.in)

		def toUpdate = [:]

		while (true) {
			println "Enter module name to update, or done to continue"

			def input = scanner.nextLine()

			if (input == "done") {
				break
			}

			// Bump all versions. To be used when buildscript changes are made.
			if (input == "allPatch") {
				project.getChildProjects().values().forEach {
					if (it.name == "deprecated" || it.name == "fabric-api-bom" || it.name == "fabric-api-catalog") {
						return
					}

					toUpdate.put(it, 2)
				}

				break
			}

			def subProject = project.childProjects[input] ?: project.childProjects["deprecated"].childProjects[input]

			if (!subProject) {
				println "Could not find project with name: $input"
				continue
			}

			while (true) {
				println "Bump version for ${subProject.name}:"
				println "0) Bump Major"
				println "1) Bump Minor"
				println "2) Bump Patch"

				input = scanner.nextLine()

				if (!(input in ["0", "1", "2"])) {
					println "Invalid input"
					continue
				}

				toUpdate.put(subProject, input as Integer)
				break
			}
		}

		while (true) {
			def temp = [:]

			toUpdate.keySet().forEach { p ->
				project.allprojects.each { cp ->
					if (cp.name == "deprecated" || cp.name == "fabric-api" || cp.name == "fabric-api-bom" || cp.name == "fabric-api-catalog") {
						return
					}

					def config = cp.configurations.api
					config.allDependencies.forEach { dep ->
						if (dep.name == p.name) {
							if (!toUpdate.containsKey(cp)) {
								println "Bumping patch of ${cp.name} as it depends on ${p.name}"

								temp.put(cp, 2) // Bump patch
							}
						}
					}
				}
			}

			if (temp.isEmpty()) {
				break
			}

			toUpdate.putAll(temp)
		}

		def gpFile = project.file("gradle.properties")
		def props = project.properties
		def text = gpFile.text

		toUpdate.forEach { p, i ->
			def version = props."${p.name}-version"

			if (!version) {
				throw new NullPointerException("Could not find version for " + p.name)
			}

			def split = version.split("\\.")
			split[i] = (split[i] as Integer) + 1
			for (j in (i + 1) ..< split.length) {
				split[j] = 0
			}
			def newVersion = split.join(".")

			println "${p.name}: $version -> $newVersion"

			text = text.replace(
					"${p.name}-version=$version",
					"${p.name}-version=$newVersion"
					)
		}

		gpFile.text = text
	}
}
