/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
import org.apache.tools.ant.filters.ReplaceTokens

plugins {
    id 'org.hibernate.build.xjc-jakarta'
}

description = 'Hibernate\'s core ORM functionality'

apply from: rootProject.file( 'gradle/relocated-published-java-module.gradle' )
apply plugin: 'org.hibernate.orm.antlr'
apply plugin: 'org.hibernate.matrix-test'

configurations {
    tests {
        description = 'Configuration for the produced test jar'
    }
}


dependencies {
    api jakartaLibs.jpa
    api jakartaLibs.jta

    implementation libs.hibernateModels
    implementation libs.hibernateModelsJandex
    implementation libs.jandex
    implementation libs.classmate
    implementation libs.byteBuddy

    implementation jakartaLibs.jaxbApi
    implementation jakartaLibs.jaxb
    implementation jakartaLibs.inject

    implementation libs.antlrRuntime

    compileOnly jakartaLibs.jacc
    compileOnly jakartaLibs.validation
    compileOnly jakartaLibs.cdi
    compileOnly jakartaLibs.jsonbApi
    compileOnly libs.jackson
    compileOnly libs.jacksonXml
    compileOnly dbLibs.postgresql

//    annotationProcessor project( ":annotation-descriptor-generator" )
    compileOnly project( ":annotation-descriptor-generator" )

    testImplementation project(':hibernate-testing')
    testImplementation project(':hibernate-ant')
    testImplementation testLibs.shrinkwrapApi
    testImplementation testLibs.shrinkwrap
    testImplementation testLibs.shrinkwrapDescriptors
    testImplementation testLibs.shrinkwrapDescriptorsApi
    testImplementation jakartaLibs.cdi
    testImplementation jakartaLibs.jacc
    testImplementation jakartaLibs.validation
    testImplementation jakartaLibs.el
    testImplementation( libs.validator ) {
        // for test runtime
        transitive = true
    }
    testImplementation "joda-time:joda-time:2.3"
    testImplementation dbLibs.h2
    testImplementation libs.hibernateModelsJandex

    testRuntimeOnly libs.byteBuddy
    testRuntimeOnly testLibs.weld
    testRuntimeOnly testLibs.wildFlyTxnClient
    testImplementation jakartaLibs.jsonb
    testImplementation libs.jackson
    testRuntimeOnly libs.jacksonXml
    testRuntimeOnly libs.jacksonJsr310

    testAnnotationProcessor project( ':hibernate-processor' )

    // NOTE: it seems like, since 4.10, the Antlr Tool no longer defines
    // transitive dep on the corresponding Antlr Runtime.  At least, I get
    // errors about mismatched versions if I do not include the runtime
    // dependency here.
    antlr libs.antlr
    antlr libs.antlrRuntime

    xjc jakartaLibs.xjc
    xjc jakartaLibs.jaxb
    xjc rootProject.fileTree(dir: 'patched-libs/jaxb2-basics', include: '*.jar')
}

jar {
    manifest {
        attributes(
                'Main-Class': 'org.hibernate.Version'
        )
    }
}

ext {
    jaxbTargetDir = project.file( "${buildDir}/generated/sources/xjc/main" )
}

sourceSets {
    test {
        resources {
            srcDir 'src/test/resources'
            srcDir 'src/test/bundles'
        }
    }
}

xjc {
    outputDirectory = project.jaxbTargetDir

    schemas {
        cfg {
            xsdFile = 'src/main/resources/org/hibernate/xsd/cfg/legacy-configuration-4.0.xsd'
            xjcBindingFile = 'src/main/xjb/hbm-configuration-bindings.xjb'
        }
        hbm {
            xsdFile = file( 'src/main/resources/org/hibernate/xsd/mapping/legacy-mapping-4.0.xsd' )
            xjcBindingFile = file( 'src/main/xjb/hbm-mapping-bindings.xjb' )
            xjcExtensions += ['inheritance', 'simplify']
        }
        configuration {
            xsdFile = file( 'src/main/resources/org/hibernate/xsd/cfg/configuration-3.2.0.xsd' )
            xjcBindingFile = file( 'src/main/xjb/configuration-bindings.xjb' )
            xjcExtensions += ['inheritance', 'simplify']
        }
        mapping {
            xsdFile = file( 'src/main/resources/org/hibernate/xsd/mapping/mapping-7.0.xsd' )
            xjcBindingFile = file( 'src/main/xjb/mapping-bindings.xjb' )
            xjcExtensions += ['inheritance', 'simplify']
        }
    }
}

task copyBundleResourcesXml (type: Copy) {
    inputs.property( "db", db )
    inputs.property( "dbHost", dbHost )
    ext {
        bundlesTargetDir = file( "${buildDir}/bundles" )
        // Escape
        bundleTokens = [
                'db.dialect' : dbBundle[db]['db.dialect'].replace("&", "&amp;"),
                'jdbc.driver' : dbBundle[db]['jdbc.driver'].replace("&", "&amp;"),
                'jdbc.user' : dbBundle[db]['jdbc.user'].replace("&", "&amp;"),
                'jdbc.pass' : dbBundle[db]['jdbc.pass'].replace("&", "&amp;"),
                'jdbc.url' : dbBundle[db]['jdbc.url'].replace("&", "&amp;"),
                'jdbc.datasource' : dbBundle[db]['jdbc.datasource'].replace("&", "&amp;"),
                'connection.init_sql' : dbBundle[db]['connection.init_sql'].replace("&", "&amp;")
        ]
        ext.bundleTokens['buildDirName'] = project.relativePath( buildDir )
    }

    from('src/test/bundles/templates') {
        include '**/*.xml'
    }
    into ext.bundlesTargetDir
    filter( ReplaceTokens, tokens: ext.bundleTokens)

    doFirst {
        ext.bundlesTargetDir.mkdirs()
    }
}

task copyBundleResourcesNonXml (type: Copy) {
    inputs.property( "db", db )
    ext {
        bundlesTargetDir = file( "${buildDir}/bundles" )
        // Escape
        bundleTokens = dbBundle[db]
        ext.bundleTokens['buildDirName'] = project.relativePath( buildDir )
    }

    from('src/test/bundles/templates') {
        exclude '**/*.xml'
    }
    into ext.bundlesTargetDir
    filter( ReplaceTokens, tokens: ext.bundleTokens)

    doFirst {
        ext.bundlesTargetDir.mkdirs()
    }
}

task copyBundleResources (type: Copy) {
    inputs.property( "db", db )
    dependsOn tasks.copyBundleResourcesXml
    dependsOn tasks.copyBundleResourcesNonXml
}

processTestResources {
    dependsOn copyBundleResources
    duplicatesStrategy = DuplicatesStrategy.INCLUDE
}

sourcesJar {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

task testJar(type: Jar, dependsOn: testClasses) {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    archiveClassifier.set( 'test' )
    from sourceSets.test.output
}

artifacts {
    tests testJar
}

tasks.register( "generateAnnotationClasses", JavaCompile ) {
    description = "Generate concrete classes for Hibernate and JPA annotations"

    source = sourceSets.main.allJava
    include "org/hibernate/annotations/*"
    classpath = sourceSets.main.runtimeClasspath + sourceSets.main.compileClasspath
    options.annotationProcessorPath = sourceSets.main.compileClasspath
    options.compilerArgs = [
            "-proc:only",
            "-processor",
            "org.hibernate.orm.build.annotations.ClassGeneratorProcessor"
    ]

    destinationDirectory.set( project.layout.buildDirectory.dir( "generated/sources/annotations/" ) )
}

task generateEnversStaticMetamodel(
        type: JavaCompile,
        description: "Generate the Hibernate Envers revision entity static metamodel classes." ) {
    source = sourceSets.main.java
    // we only want to include these specific classes for metamodel generation.
    // if envers adds any additional revision entity classes, they must be listed here.
    include 'org/hibernate/envers/DefaultRevisionEntity.java'
    include 'org/hibernate/envers/DefaultTrackingModifiedEntitiesRevisionEntity.java'
    include 'org/hibernate/envers/enhanced/SequenceIdRevisionEntity.java'
    include 'org/hibernate/envers/enhanced/SequenceIdTrackingModifiedEntitiesRevisionEntity.java'

    classpath = sourceSets.main.runtimeClasspath + sourceSets.test.compileClasspath
    options.compilerArgs = [
            "-proc:only",
            "-processor",
            "org.hibernate.processor.HibernateProcessor"
    ]

    // put static metamodel classes back out to the source tree since they're version controlled.
    destinationDirectory = new File( "${projectDir}/src/main/java" )
}

tasks.withType( Test.class ).each { test ->
    test.systemProperty 'file.encoding', 'utf-8'
    // Allow creating a function in HSQLDB for this Java method
    test.systemProperty 'hsqldb.method_class_names', 'org.hibernate.orm.test.jpa.transaction.TransactionTimeoutTest.sleep'

    // See org.hibernate.boot.model.naming.NamingHelperTest.DefaultCharset.set
    test.jvmArgs( ['--add-opens', 'java.base/java.nio.charset=ALL-UNNAMED'] )
    // Weld needs this to generate proxies
    test.jvmArgs( ['--add-opens', 'java.base/java.security=ALL-UNNAMED'] )
    test.jvmArgs( ['--add-opens', 'java.base/java.lang=ALL-UNNAMED'] )

    //Avoid Log4J2 classloader leaks:
    test.jvmArgs( ['-Dlog4j2.disableJmx=true'] )

    test.beforeTest { descriptor ->
        //println "Starting test: " + descriptor
    }
    if ( project.db == "h2" || project.db == "hsqldb" ) {
        // Parallel test runs when running with in-memory databases
        test.maxParallelForks = Runtime.runtime.availableProcessors().intdiv( 2 ) ?: 1
    }
}

tasks.named( "javadoc", Javadoc ) {
    configure(options) {
        overview = rootProject.file( "shared/javadoc/overview.html" )
    }
}

tasks.sourcesJar.dependsOn ':hibernate-core:generateGraphParser'
tasks.sourcesJar.dependsOn ':hibernate-core:generateHqlParser'
tasks.sourcesJar.dependsOn ':hibernate-core:generateSqlScriptParser'
tasks.sourcesJar.dependsOn ':hibernate-core:generateOrderingParser'