buildscript {
	ext.isCI = System.getenv('GITHUB_ACTION')
	ext.javaFormatVersion = '0.0.43'
}

plugins {
	id 'base'
	id 'io.spring.dependency-management' version '1.1.6'
	id 'io.spring.javaformat' version "${javaFormatVersion}"
	id 'com.github.spotbugs' version '6.0.26'
	id 'org.ajoberstar.grgit' version '5.2.2'
}

description = 'Spring Functions Catlog'

ext {
	javaProjects = subprojects - project(':spring-functions-catalog-bom')
}

apply from: 'dependencies.gradle'

ext {
	modifiedFiles = files().from { files(grgit.status().unstaged.modified).filter { f -> f.name.endsWith('.java') } }
	modifiedFiles.finalizeValueOnRead()

	javadocLinks = [
			'https://docs.oracle.com/en/java/javase/17/docs/api/',
			'https://jakarta.ee/specifications/platform/10/apidocs/',
			'https://docs.spring.io/spring-framework/docs/current/javadoc-api',
			'https://docs.spring.io/spring-integration/docs/current/api/'
	] as String[]
}

allprojects {
	group = 'org.springframework.cloud.fn'

	repositories {
		mavenCentral()
		maven { url 'https://repo.spring.io/milestone' }
		if (version.endsWith('SNAPSHOT')) {
			maven { url 'https://repo.spring.io/snapshot' }
		}
//		maven { url 'https://repo.spring.io/libs-staging-local' }
	}

	apply plugin: 'io.spring.dependency-management'

	dependencyManagement {
		resolutionStrategy {
			cacheChangingModulesFor 0, 'seconds'
		}
		applyMavenExclusions = false
		generatedPomCustomization {
			enabled = false
		}

		imports {
			mavenBom "io.debezium:debezium-bom:$debeziumVersion"
			mavenBom "io.awspring.cloud:spring-cloud-aws-dependencies:$springCloudAwsVersion"
			mavenBom "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
			mavenBom "org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion"
			mavenBom "ai.djl:bom:$djlVersion"
		}
	}
}

configure(javaProjects) { subproject ->
	apply plugin: 'java-library'
	apply plugin: 'eclipse'
	apply plugin: 'idea'
	apply plugin: 'checkstyle'
	apply plugin: 'io.spring.javaformat'
	apply from: "${rootDir}/publish-maven.gradle"

	sourceSets {
		test {
			resources {
				srcDirs = ['src/test/resources', 'src/test/java']
			}
		}
	}

	java {
		withJavadocJar()
		withSourcesJar()
		registerFeature('optional') {
			usingSourceSet(sourceSets.main)
		}
	}

	compileJava {
		options.release = 17
	}

	compileTestJava {
		sourceCompatibility = JavaVersion.VERSION_17
		targetCompatibility = JavaVersion.VERSION_17
		options.encoding = 'UTF-8'
	}

	tasks.withType(JavaCompile).configureEach {
		options.fork = true
	}

	tasks.withType(Javadoc) {
		options.addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
	}

	eclipse {
		project {
			natures += 'org.springframework.ide.eclipse.core.springnature'
		}
	}

	checkstyle {
		toolVersion = '10.3'
		configDirectory = rootProject.file('etc/checkstyle')
	}

	// dependencies that are common across all java projects
	dependencies {
		annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'

		if (subproject.name != 'spring-config-common') {
			api project(':spring-config-common')
		}

		api 'org.springframework.boot:spring-boot-starter-validation'
		api 'org.springframework.boot:spring-boot-starter-json'
		api 'org.springframework.boot:spring-boot-starter-integration'
		api 'com.jayway.jsonpath:json-path'

		def spotbugsAnnotations = "com.github.spotbugs:spotbugs-annotations:${spotbugs.toolVersion.get()}"
		compileOnly spotbugsAnnotations
		testCompileOnly spotbugsAnnotations

		testImplementation 'org.springframework.boot:spring-boot-starter-test'
		testImplementation 'org.springframework.integration:spring-integration-test'
		testImplementation 'io.projectreactor:reactor-test'
		testImplementation 'org.awaitility:awaitility'
		testImplementation 'org.testcontainers:junit-jupiter'

		// NOTE: We explicitly specify checkstyle dep before javaformat checkstyle due to antlr class mismatch
		checkstyle("com.puppycrawl.tools:checkstyle:${checkstyle.toolVersion}")
		checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}")
	}

	[compileJava, compileTestJava]*.options*.compilerArgs = ['-Xlint:all,-options,-processing', '-parameters']

	test {
		maxHeapSize = '2g'
		jvmArgs '-XX:+HeapDumpOnOutOfMemoryError'
		useJUnitPlatform()

		enableAssertions = false

		logging.captureStandardOutput(LogLevel.INFO)
	}

	tasks.register('updateCopyrights') {
		onlyIf { !isCI }
		inputs.files(modifiedFiles.filter { f -> f.path.contains(subproject.name) })
		outputs.dir('build/classes')

		doLast {
			def now = Calendar.instance.get(Calendar.YEAR) as String
			inputs.files.each { file ->
				def line
				file.withReader { reader ->
					while (line = reader.readLine()) {
						def matcher = line =~ /Copyright (20\d\d)-?(20\d\d)?/
						if (matcher.count) {
							def beginningYear = matcher[0][1]
							if (now != beginningYear && now != matcher[0][2]) {
								def years = "$beginningYear-$now"
								def sourceCode = file.getText('UTF-8')
								sourceCode = sourceCode.replaceFirst(/20\d\d(-20\d\d)?/, years)
								file.text = sourceCode
								println "Copyright updated for file: $file"
							}
							break
						}
					}
				}
			}
		}
	}

	compileJava.dependsOn updateCopyrights

	jar {
		manifest {
			attributes(
					'Implementation-Version': project.version,
					'Created-By': "JDK ${System.properties['java.version']} (${System.properties['java.specification.vendor']})",
					'Implementation-Title': subproject.name,
					'Implementation-Vendor-Id': subproject.group,
					'Implementation-Vendor': 'VMware, Inc.',
					'Implementation-URL': 'https://spring.io/projects/spring-functions-catalog',
					'Automatic-Module-Name': subproject.name.replace('-', '.')
			)
		}

		from("${rootProject.projectDir}") {
			include 'LICENSE.txt'
			into 'META-INF'
		}
	}

	publishing {
		publications {
			mavenJava(MavenPublication) {
				suppressAllPomMetadataWarnings()
				from components.java
			}
		}
	}

}
