import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent

plugins {
	id 'java'
	id 'java-library'
	id 'jacoco'
	id 'checkstyle' 
	id 'application'
	id 'org.springframework.boot' version '3.3.5'
	id 'io.spring.dependency-management' version '1.1.6'
	id 'org.springdoc.openapi-gradle-plugin' version '1.9.0'
}

group = 'ai'

java {
	sourceCompatibility = '17'
	targetCompatibility = '17'
}

repositories {
	mavenCentral()
}

dependencies {
	annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.3.5'
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation 'org.hibernate.validator:hibernate-validator'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'

	implementation 'dev.langchain4j:langchain4j:0.36.0'
    implementation 'dev.langchain4j:langchain4j-core:0.36.0'
    implementation 'dev.langchain4j:langchain4j-embeddings:0.36.0'
    implementation 'dev.langchain4j:langchain4j-pgvector:0.36.0'
    implementation 'dev.langchain4j:langchain4j-easy-rag:0.36.0'
	implementation 'dev.langchain4j:langchain4j-open-ai:0.36.0'
	implementation 'dev.langchain4j:langchain4j-mistral-ai:0.36.0'

    implementation 'org.aspectj:aspectjrt:1.9.22.1'
    implementation 'org.aspectj:aspectjweaver:1.9.22.1'

	implementation platform('org.dizitart:nitrite-bom:4.3.0')
	implementation 'org.dizitart:nitrite'
	implementation 'org.dizitart:nitrite-support'
	implementation 'org.dizitart:nitrite-mvstore-adapter'
	implementation 'org.dizitart:nitrite-jackson-mapper'

	implementation 'net.sourceforge.argparse4j:argparse4j:0.9.0'
	implementation 'org.jobrunr:jobrunr-spring-boot-3-starter:7.3.1'
	implementation 'me.paulschwarz:spring-dotenv:4.0.0'
	
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
	testImplementation 'org.awaitility:awaitility:4.2.2'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
    
    testImplementation 'org.testcontainers:testcontainers:1.20.3'
    testImplementation 'org.testcontainers:junit-jupiter:1.20.3'

	compileOnly 'org.projectlombok:lombok:1.18.34'
	annotationProcessor 'org.projectlombok:lombok:1.18.34'
	testCompileOnly 'org.projectlombok:lombok:1.18.34'
	testAnnotationProcessor 'org.projectlombok:lombok:1.18.34'
}

application {
    applicationDefaultJvmArgs = ["-Dapp.version=${version}"]
}

openApi {
	groupedApiMappings.set(['http://localhost:1985/api/docs/backend': 'swagger-backend.json',
                            'http://localhost:1985/api/docs/app': 'swagger-app.json',
							'http://localhost:1985/api/docs/rag': 'swagger-rag.json',
							'http://localhost:1985/api/docs/raag': 'swagger-raag.json'])
    outputDir.set(file("$buildDir/docs/api"))
    waitTimeInSeconds.set(10)
    customBootRun {
        args.set(['--spring.profiles.active=test']) 
    }
}

checkstyle {
	toolVersion '10.20.1'
    config = rootProject.resources.text.fromFile('backend/checkstyle.xml')
    ignoreFailures = false
    maxWarnings = 0
}

bootJar {
    manifest {
        attributes(
            'Implementation-Title': project.name,
            'Implementation-Version': version
        )
    }
}

jar {
    manifest {
        attributes(
            'Implementation-Title': project.name,
            'Implementation-Version': version
        )
    }
}

test {
	useJUnitPlatform()
    finalizedBy jacocoTestReport
}

jacocoTestReport {
    dependsOn test
    reports {
        xml.required = true
        html.required = true
        csv.required = true
    }
}

jacoco {
    toolVersion = "0.8.12"
}

tasks.register("bootProdRun") {
    group = "application"
    description = "Runs this project as a Spring Boot application with the PROD profile"
    doFirst {
        tasks.bootRun.configure {
            systemProperty("spring.profiles.active", "prod")
        }
    }
}

tasks.register('copyWebApp', Copy) {
	dependsOn(':frontend:pnpmBuild')
	from "$rootDir/frontend/dist"
	into "$buildDir/resources/main/static/."
}

tasks.named('compileJava') {
	dependsOn(':frontend:pnpmBuild')
}

tasks.named('processResources') {
	dependsOn('copyWebApp')
}

// Based on : https://stackoverflow.com/a/36130467/8102448
tasks.withType(Test) {
    testLogging {
        events TestLogEvent.FAILED,
               TestLogEvent.PASSED,
               TestLogEvent.SKIPPED
        exceptionFormat TestExceptionFormat.FULL
        showExceptions true
        showCauses true
        showStackTraces true

        afterSuite { desc, result ->
            if (!desc.parent) {
                def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)"
                def startItem = '|  ', endItem = '  |'
                def repeatLength = startItem.length() + output.length() + endItem.length()
                println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
            }
        }
    }
}