/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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.
 */

plugins {
    id 'groovy'
    id 'project-report'
}

version = projectVersion
group = 'org.apache.grails.testing'

dependencies {
    implementation platform(project(':grails-bom'))

    testImplementation project(':grails-async')
    testImplementation project(':grails-codecs')
    testImplementation project(':grails-controllers')
    testImplementation project(':grails-databinding')
    testImplementation project(':grails-datasource')
    testImplementation project(':grails-domain-class')
    testImplementation project(':grails-interceptors')
    testImplementation project(':grails-rest-transforms')
    testImplementation project(':grails-services')
    testImplementation project(':grails-url-mappings')
    testImplementation project(':grails-spring')
    testImplementation project(':grails-test-suite-base')
    testImplementation project(':grails-testing-support-core')
    testImplementation 'org.apache.groovy:groovy'
    testImplementation 'org.apache.groovy:groovy-test-junit5'
    testImplementation 'org.junit.jupiter:junit-jupiter-api'
    testImplementation 'com.fasterxml.jackson.core:jackson-databind'
    testImplementation project(':grails-data-hibernate5-core')
    testImplementation project(':grails-gsp')
    if(System.getenv('SITEMESH3_TESTING_ENABLED') == 'true') {
        implementation project(':grails-sitemesh3')
    }
    else {
        implementation project(':grails-layout')
    }
    testImplementation project(':grails-testing-support-datamapping'), {
        // This is a local project dependency
        exclude module: 'grails-testing-support-core'
        exclude module: 'grails-rest-transforms'
    }
    testImplementation project(':grails-testing-support-web'), {
        // This is a local project dependency
        exclude module: 'grails-testing-support-core'
        exclude module: 'grails-rest-transforms'
    }
    testImplementation project(':grails-datamapping-validation')
    testImplementation 'org.objenesis:objenesis'

    testCompileOnly 'jakarta.servlet:jakarta.servlet-api'
    testCompileOnly 'org.springframework:spring-test', {
        // MockHttpServletRequest/Response/Context used in many classes
    }

    testRuntimeOnly 'com.h2database:h2'
    testRuntimeOnly 'org.apache.tomcat:tomcat-jdbc'
    testRuntimeOnly 'org.aspectj:aspectjrt'
    testRuntimeOnly 'org.aspectj:aspectjweaver'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.springframework:spring-aspects'


    // Testing
    testImplementation('org.spockframework:spock-core') { transitive = false }
    // Required by Spock's Mocking
    testRuntimeOnly 'net.bytebuddy:byte-buddy'
}

def isolatedTestPatterns = [
        isolatedTestsOne              : [
                'org.grails.core.DefaultGrailsControllerClassSpec',
                'org.grails.web.util.WebUtilsTests'
        ],
        isolatedTestsTwo              : [
                'grails.test.mixin.UrlMappingsTestMixinTests',
                'grails.test.mixin.SetupTeardownInvokeTests',
                'grails.test.mixin.TestMixinSetupTeardownInvokeTests'
        ],
        isolatedRestRendererTests     : [
                '*.rest.render.*Spec'
        ],
        isolatedPersonTests           : [
                'org.grails.validation.TestingValidationSpec',
                'org.grails.validation.CascadingErrorCountSpec'
        ],
        isolatedRestfulControllerTests: [
                'grails.test.mixin.RestfulControllerSpec',
                'grails.test.mixin.ResourceAnnotationRestfulControllerSpec'
        ]
]

isolatedTestPatterns.keySet().each { taskName ->
    tasks.register(taskName, Test).configure { Test tTask ->
        tTask.onlyIf {
            ![
                    'onlyFunctionalTests',
                    'onlyHibernate5Tests',
                    'onlyMongodbTests',
                    'skipCoreTests',
                    'skipTests'
            ].find {
                project.hasProperty(it)
            }
        }
        tTask.group = 'verification'
        tTask.filter.includePatterns = isolatedTestPatterns[taskName]
    }
}

tasks.named('isolatedTestsTwo', Test).configure {
    maxParallelForks = 1
    forkEvery = 100
}

tasks.withType(Test).configureEach {
    onlyIf {
        ![
                'onlyHibernate5Tests',
                'onlyMongodbTests',
                'skipCoreTests'
        ].find {
            project.hasProperty(it)
        }
    }

    onlyIf {
        !project.hasProperty('onlyFunctionalTests')
    }
    useJUnitPlatform()
    maxParallelForks = configuredTestParallel
    forkEvery = isCiBuild ? 25 : 100
    maxHeapSize = isCiBuild ? '768m' : '1024m'
    jvmArgs('--add-opens=java.base/java.lang=ALL-UNNAMED', '--add-opens=java.base/java.util=ALL-UNNAMED')
}

tasks.named('test', Test).configure {
    onlyIf {
        ![
                'onlyFunctionalTests',
                'onlyHibernate5Tests',
                'onlyMongodbTests',
                'skipCoreTests',
                'skipTests'
        ].find {
            project.hasProperty(it)
        }
    }

    filter.excludePatterns = isolatedTestPatterns.values().flatten()
    dependsOn(provider {
        tasks.findAll({
            isolatedTestPatterns.containsKey(it.name)
        })
    })
}

apply {
    // java-configuration must be applied first since tasks are now lazy registered
    from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
}

tasks.withType(Groovydoc).configureEach {
    // tests do not have groovydoc
    enabled = false
}
