/*
 * Copyright (c) 2011-2026 VMware Inc. or its affiliates, All Rights Reserved.
 *
 * Licensed 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
 *
 *   https://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.
 */

buildscript {
	repositories {
		mavenCentral()
	}
}

plugins {
	id "java-platform"
	id "maven-publish"
	//applied in rootProject if credentials provided (see below):
	id "com.jfrog.artifactory" version "6.0.4" apply false
}

apply from: "gradle/releaser.gradle"

group = 'io.projectreactor'
description = 'Bill of materials to make sure a consistent set of versions is used for Reactor 3.'

repositories {
	mavenCentral()
	maven { url = "https://oss.sonatype.org/content/repositories/releases/" }
	if (version.endsWith('-SNAPSHOT')) {
		mavenLocal()
		maven { url = 'https://repo.spring.io/snapshot' }
	}
}

dependencies {
	constraints {
		// Reactor Core
		api "io.projectreactor:reactor-core:$reactorCoreVersion"
		api "io.projectreactor:reactor-test:$reactorCoreVersion"
		api "io.projectreactor:reactor-tools:$reactorCoreVersion"
		api "io.projectreactor:reactor-core-micrometer:$reactorCoreVersion"
		// Reactor Addons
		api "io.projectreactor.addons:reactor-extra:$reactorAddonsVersion"
		api "io.projectreactor.addons:reactor-adapter:$reactorAddonsVersion"
		// Reactor Netty 1.x for Netty 4.1
		api "io.projectreactor.netty:reactor-netty:$reactorNettyVersion"
		api "io.projectreactor.netty:reactor-netty-core:$reactorNettyVersion"
		api "io.projectreactor.netty:reactor-netty-http:$reactorNettyVersion"
		api "io.projectreactor.netty:reactor-netty-http-brave:$reactorNettyVersion"
		api "io.projectreactor.netty:reactor-netty-quic:$reactorNettyVersion"
		// Reactor Pool
		api "io.projectreactor.addons:reactor-pool:$reactorPoolVersion"
		api "io.projectreactor.addons:reactor-pool-micrometer:$reactorPoolVersion"
		//Reactor Kotlin Extensions
		api "io.projectreactor.kotlin:reactor-kotlin-extensions:$reactorKotlinExtensionsVersion"
	}
}


static def qualifyVersion(String v) {
	v = v.toUpperCase()
	if (v.startsWith("DYSPROSIUM")) {
		//old scheme
		def qualifier = v.replaceFirst("DYSPROSIUM-", "")
		if (qualifier == 'RELEASE') return "RELEASE"
		if (qualifier.matches("(?:SR)\\d+")) return "RELEASE" //old SR
		if (qualifier.matches("(?:M|RC)\\d+")) return "MILESTONE"
		if (qualifier == "BUILD-SNAPSHOT") return "SNAPSHOT"

		return "BAD"
	}
	//new scheme: major.minor.patch[.hotfix][-qualifier]
	//all numeric segments use (?:...) non-capturing groups since only the qualifier is needed; it lands at group(1)
	def match = v =~ /^(?:\d+)\.(?:\d+)\.(?:\d+)(?:\.\d+)?(?:-(.+))?$/
	if (!match.matches()) return "BAD"

	def qualifier = match.group(1)
	if (qualifier == null || qualifier.isEmpty()) return "RELEASE"
	if (qualifier.matches("(?:M|RC)\\d+")) return "MILESTONE"
	if (qualifier == "SNAPSHOT") return "SNAPSHOT"

	return "BAD"
}

static def outputToGha(String versionType, String fullVersion) {
	def ghaFilename = System.getenv("GITHUB_OUTPUT")
	if (ghaFilename == null) {
		println "::set-output name=versionType::$versionType"
		println "::set-output name=fullVersion::$fullVersion"
	}
	else {
		println "using GITHUB_OUTPUT file"
		def ghaFile = new File(ghaFilename)
		ghaFile.withWriterAppend {
			it.newLine()
			it.append("versionType=$versionType")
			it.newLine()
			it.append("fullVersion=$fullVersion")
		}
	}
}

task qualifyVersionGha() {
	def projectName = project.name
	doLast {
		def versionType = qualifyVersion("$version")
		//we ensure that if at least _one_ submodule version is BAD, we only output versionType=BAD + job fails
		if (versionType == "BAD") {
			outputToGha(versionType, version)
			println "::error ::Unable to parse $version to a VersionNumber with recognizable qualifier"
			throw new TaskExecutionException(tasks.getByName("qualifyVersionGha"), new IllegalArgumentException("Unable to parse $version to a VersionNumber with recognizable qualifier"))
		}
		println "Recognized $version as $versionType"

		//only output the versionType and fullVersion for the main artifact
		if (projectName == 'reactor-bom') {
			outputToGha(versionType, version)
		}
	}
}

publishing {
	repositories {
		maven {
			name = "mock"
			url = "${rootProject.layout.buildDirectory.get().asFile}/mockRepo"
		}
		if (qualifyVersion("$version") in ["RELEASE", "MILESTONE"]) {
			maven {
				name = "sonatype"
				url = "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/"
				credentials {
					username findProperty("sonatypeUsername")
					password findProperty("sonatypePassword")
				}
			}
		}
	}

	publications {
		mavenJava(MavenPublication) {
			artifactId = 'reactor-bom'
			from components.javaPlatform
			pom {
				afterEvaluate {
					name = 'Project Reactor 3 Release Train - BOM'
					description = project.description
				}
				url = 'https://projectreactor.io'
				organization {
					name = 'reactor'
					url = 'https://github.com/reactor'
				}
				licenses {
					license {
						name = 'The Apache Software License, Version 2.0'
						url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
						distribution = 'repo'
					}
				}
				scm {
					url = 'https://github.com/reactor/reactor'
					connection = 'scm:git:git://github.com/reactor/reactor'
					developerConnection = 'scm:git:git://github.com/reactor/reactor'
				}
				issueManagement {
					system = "GitHub Issues"
					url = "https://github.com/reactor"
				}
				developers {
					developer {
						id = 'simonbasle'
						name = 'Simon Baslé'
						email = 'sbasle at vmware.com'
					}
					developer {
						id = 'violetagg'
						name = 'Violeta Georgieva'
						email = 'violetag at vmware.com'
					}
					developer {
						id = 'odokuka'
						name = 'Oleh Dokuka'
						email = 'odokuka at vmware.com'
					}
				}
			}
			versionMapping {
				usage('java-api') {
					fromResolutionResult()
				}
				usage('java-runtime') {
					fromResolutionResult()
				}
			}
		}
	}
}

if (rootProject.hasProperty("artifactory_publish_password")) {
	apply plugin: "com.jfrog.artifactory"

	artifactoryPublish {
		publications(publishing.publications.mavenJava)
	}
}

if (qualifyVersion("$version") in ["RELEASE", "MILESTONE"] || rootProject.hasProperty("forceSigning")) {
	apply plugin: 'signing'

	signing {
		//requiring signature if there is a publish task that is not to MavenLocal
		required {  gradle.taskGraph.allTasks.any { it.name.toLowerCase().contains("publish")	&& !it.name.contains("MavenLocal") } }
		def signingKey = findProperty("signingKey")
		def signingPassword = findProperty("signingPassword")

		useInMemoryPgpKeys(signingKey, signingPassword)

		afterEvaluate {
			sign publishing.publications.mavenJava
		}
	}
}
