buildscript {
	apply from: 'gradle/repositories.gradle', to: buildscript

	dependencies {
		<some self company made packages in a repository>

		classpath 'org.tukaani:xz:1.9'
		classpath 'org.apache.commons:commons-compress:1.21'
	}
}

plugins {
	id 'net.researchgate.release' version '2.6.0'
	id 'com.github.ben-manes.versions' version '0.15.0'
	id 'com.github.spotbugs' version '5.0.13' apply false
	id 'org.cyclonedx.bom' version '1.5.0' apply false
	id 'com.jfrog.artifactory' version '4.32.0'
}

apply plugin: 'base'
apply plugin: 'project-report'

allprojects {
	apply plugin: 'eclipse'
	apply plugin: 'idea'
	apply plugin: 'custom-versioning'

	group = 'com.company.product'

	if( project.hasProperty( 'newVersionCommit' ) && Boolean.valueOf( newVersionCommit ) )
	{
		// just use the first three version parts (major.minor.patch) for new version commits
		customVersioning {
			releaseVersionPrefix = ''
			releaseVersionSuffix = ''
			branchVersionPrefix = ''
			branchVersionSuffix = ''
		}
	}
	else if( project.hasProperty( 'customBuildNumber' ) )
	{
		customVersioning {
			releaseVersionPrefix = ''
			releaseVersionSuffix = ".${customBuildNumber}"
			branchVersionPrefix = ''
			branchVersionSuffix = ".${customBuildNumber}"
		}
	}
	else if( System.getenv().CUSTOM_BUILD_NUMBER )
	{
		customVersioning {
			releaseVersionPrefix = ''
			releaseVersionSuffix = ".${System.getenv().CUSTOM_BUILD_NUMBER}"
			branchVersionPrefix = ''
			branchVersionSuffix = ".${System.getenv().CUSTOM_BUILD_NUMBER}"
		}
	}
	else
	{
		customVersioning {
			releaseVersionPrefix = ''
			releaseVersionSuffix = ".${customVersioning.getCurrentBuildNumber()}"
			branchVersionPrefix = ''
			branchVersionSuffix = ".${customVersioning.getCurrentBuildNumber()}"
		}
	}

	version = customVersioning.getCustomVersion()

	ext {
		productShortName = 'product'
		productDisplayName = 'product'
		productVendorName = 'companyName'
		productVendorURL = '<vendorURL>'
		distBaseName = "${productShortName}-${name}"

		jxBrowserVersion = '7.36'
		jdkVersionClient = '11.0.19_7'
		jdkVersion = '17.0.7_7'

		postgresBaseVersion = '14.5'
		postgresSha = 'sha256:135c62a8134dcef829a1e4f5568bfae44bcfa2c75659ff948f43c71964366aa4'
		postgresJdbcDriverVersion = '42.5.3'
	}

	apply from: "${rootProject.projectDir}/gradle/repositories.gradle"

}

def publishingProjects = ['subproject 1', 'subproject 2', 'subproject 3', 'subproject 4', 'subproject 5', 'subproject 6', 'subproject 7', 'subproject 8, 'subproject 9', 'subproject 10']

subprojects {

    if (it.name != "H"){
        apply plugin: 'java'
        apply plugin: 'com.github.spotbugs'

        if( it.name in publishingProjects )
        {

            apply plugin: 'maven-publish'
            apply plugin: 'com.jfrog.artifactory'
            apply from: "${rootProject.projectDir}/gradle/artifactory.gradle"
        }

        sourceCompatibility = JavaVersion.VERSION_11

        ext {
            springFrameworkVersion = '5.3.22'
        }

        configurations.all {
            exclude group: 'org.apache.commons', module: 'commons-logging'
            exclude group: 'commons-logging', module: 'commons-logging'
        }

        configurations.all {
            resolutionStrategy {

                eachDependency {DependencyResolveDetails details ->
                    //use consistent version of spring framework across all projects
                    if( details.requested.group == 'org.springframework' )
                    {
                        details.useVersion springFrameworkVersion
                    }
                }


                // fail eagerly on version conflict (includes transitive dependencies)
                // e.g. multiple different versions of the same dependency (group and name are equal)
                failOnVersionConflict()
                preferProjectModules()

                force "org.slf4j:slf4j-api:2.0.6"
                force 'org.jboss.logging:jboss-logging:3.3.1.Final'
                force 'commons-codec:commons-codec:1.10'
            }
        }

        spotbugs {
            ignoreFailures = true
            excludeFilter = file( "${rootProject.projectDir}/config/spotbugs/excludeFilter.xml" )
            maxHeapSize = '4g'
        }
        spotbugsMain {
            reports {
                xml.enabled true
                html.enabled true
            }
        }

        ext {
            sharedManifest = manifest {
                attributes( 'Implementation-Title': 'ProductName', 'Implementation-Version': version,
                        'Implementation-URL': '<vendorUrl> )
            }
            currentYear = getYear()

            jacksonDatabindVersion = '2.13.4.2'
            slf4jVersion = '2.0.6'
            testTempDir = file( "${buildDir}/test-tmp" )

            servletApiVersion = '3.1.0'

            springFrameworkVersion = '5.3.22'
            springSecurityVersion = '5.8.6'
            springSecurityOauth2Version = '2.5.2.RELEASE'
        }

        dependencies {
            runtimeOnly "org.tukaani:xz:1.9"
            implementation 'org.dom4j:dom4j:2.1.3'
            constraints {
                implementation( 'javax.xml.bind:jaxb-api:2.3.0' ) {
                    because 'update dependency to working version'
                }
            }

            implementation 'pull-parser:pull-parser:2.1.10'

            testImplementation "org.spockframework:spock-core:2.2-groovy-3.0"
            testImplementation 'org.codehaus.groovy:groovy-dateutil:3.0.13'
            testImplementation 'junit:junit:4.12'
            testImplementation 'org.hamcrest:hamcrest-core:1.3'
            testImplementation 'org.hamcrest:hamcrest-library:1.3'
            testImplementation 'org.spockframework:spock-core:2.2-groovy-3.0'
            testImplementation 'org.objenesis:objenesis:2.6' // used for complex mocking with Spock
            testImplementation group: 'net.bytebuddy', name: 'byte-buddy', version: '1.9.3'
            testImplementation 'org.junit.vintage:junit-vintage-engine:5.3.1' //for compatability with jUnit 4
            spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0'


        }

        jar {
            manifest {from project.sharedManifest}
        }
        sourceSets.matching {!( it.name ==~ '(main|test)' )}.all {set ->
            def jarTask = task( "${set.name}Jar", type: Jar ) {
                appendix = set.name
                description = "Assembles a jar archive containing the ${set.name} classes."
                group = 'build'
                manifest {from project.sharedManifest}
                from set.output
            }
            artifacts {
                archives jarTask
            }
        }

        test {
            doFirst {
                if( !testTempDir.exists() )
                    testTempDir.mkdirs()
            }
            systemProperties = System.properties.subMap( 'keycloak.auth-server-url' )
            systemProperty 'java.io.tmpdir', testTempDir
            systemProperty "java.locale.providers", "COMPAT,CLDR,SPI"
        }
        task allClasses {
            dependsOn {allClassesTasks( project )}
        }
        task printConfigurations {
            group = 'help'
            description 'Display all configurations of a project'
            doLast {
                printConfigs()
            }
        }

        task allDependencies( type: DependencyReportTask ) {
            group = 'help'
            description "Display all dependencies of a project - 'gradlew allDependencies' displays the dependencies of all subprojects if called on root"
        }

        afterEvaluate {project ->
            project.tasks.withType( JavaCompile ) {
                options.encoding = 'UTF-8'
            }
            project.tasks.withType( Javadoc ) {
                options.encoding = 'UTF-8'
            }
            project.tasks.withType( Tar ) {
                compression = Compression.GZIP
                extension = 'tar.gz'
            }
            project.tasks.withType( Test ) {
                ignoreFailures = true
            }
            project.tasks.withType( AbstractArchiveTask ) {
                duplicatesStrategy = DuplicatesStrategy.FAIL
            }
        }
        task cleanTmp( type: Delete ) {
            delete file( "${buildDir}/tmp" )
        }

        plugins.withType( com.company.gradle.plugins.ProductDistributionPlugin ) {
            task allInstallers {
                dependsOn createInstallers
            }
        }

        eclipse {
            pathVariables 'GRADLE_USER_HOME': gradle.gradleUserHomeDir
            project {
                natures = ['org.eclipse.buildship.core.gradleprojectnature', 'org.eclipse.jdt.groovy.core.groovyNature', 'org.eclipse.jdt.core.javanature']
            }
            classpath {
                file {
                    whenMerged {classpath -> classpath.entries.findAll {entry -> entry.kind == 'var'}*.exported = true
                    }
                }
            }
        }

        // workaround for Jenkins failing because of incremental test results
        task jenkinsTest {
            inputs.files test.outputs.files
            doLast {
                def timestamp = System.currentTimeMillis()
                if( project.testResultsDir.exists() )
                {
                    project.testResultsDir.eachFile {it.lastModified = timestamp}
                }
                if( project.testReportDir.exists() )
                {
                    project.testReportDir.eachFile {it.lastModified = timestamp}
                }
            }
        }
        check.dependsOn( jenkinsTest )

        task copyDependencies( type: Copy ) {
            from {configurations.runtime}
            into( "${buildDir}/dependency-libs" )
        }

        task artifacts {
            group = 'help'
            description = "Displays the artifacts associated with each configuration of ${project}"
            doFirst {
                configurations.findAll().each {config ->
                    println "${config}:"
                    config.allArtifacts.getFiles().each {file -> println ' ' + file
                    }
                    println ' '
                }
            }
        }
    }
    else {
        task wrapper(type: Wrapper) {
            gradleVersion = '8.5'
        }
    }
}

eclipse {
	project {
		natures = ['org.eclipse.buildship.core.gradleprojectnature', 'org.eclipse.jdt.core.javanature', 'org.eclipse.jdt.groovy.core.groovyNature']
	}
}


def allClassesTasks( project )
{
	project.sourceSets.collect {
		project.tasks[it.classesTaskName]
	}
}


def asFlatConfiguration( Configuration source )
{
	def conf = source.copy()
	conf.transitive = false
	conf
}


// debug methods
def printSourceSets()
{
	sourceSets.each {
		println it.name
		it.java.srcDirs.each {
			println it.path
		}
		it.resources.srcDirs.each {
			println it.path
		}
	}
}


def printConfigs()
{
	configurations.each {conf ->
		println "\nConfig: ${conf.name}"
		conf.each {
			println "\t${it.name}"
		}
	}
}


def printArtifacts()
{
	configurations.each {conf ->
		println "\nConfig: ${conf.name}"
		conf.allArtifacts.files.each {
			println it
		}
	}
}


def getYear()
{
	def date = new Date()
	def formattedYear = date.format( 'yyyy' )
	return formattedYear
}


apply from: 'gradle/release.gradle'

wrapper {
	gradleVersion = '7.4.2'
	distributionUrl = "https://<companyRepoServerURL>/artifactory/gradle-distributions/gradle-${gradleVersion}-all.zip"

	// reset DEFAULT_JVM_OPTS to empty string to ensure JVM takes care of defining a sensible heap size
	// more robust version of https://stackoverflow.com/a/17701809
	doLast {
		def optsEnvVar = "DEFAULT_JVM_OPTS"
		scriptFile.write scriptFile.text.replaceAll( "$optsEnvVar=[^\r\n]*", "$optsEnvVar=\"\"" )
		batchScript.write batchScript.text.replaceAll( "set $optsEnvVar=[^\r\n]*", "set $optsEnvVar=" )
	}
}