plugins {
    id "java"
    id "jacoco"
    id "io.spring.dependency-management" version "1.1.7"
    id "org.springframework.boot" version "3.5.6"
    id "org.springdoc.openapi-gradle-plugin" version "1.9.0"
    id "io.swagger.swaggerhub" version "1.3.2"
    id "com.diffplug.spotless" version "7.2.1"
    id "com.github.jk1.dependency-license-report" version "2.9"
    //id "nebula.lint" version "19.0.3"
    id "org.sonarqube" version "6.3.1.5724"
}

import com.github.jk1.license.render.*

ext {
    springBootVersion = "3.5.6"
    pdfboxVersion = "3.0.5"
    imageioVersion = "3.12.0"
    lombokVersion = "1.18.42"
    bouncycastleVersion = "1.82"
    springSecuritySamlVersion = "6.5.5"
    openSamlVersion = "4.3.2"
    commonmarkVersion = "0.26.0"
    googleJavaFormatVersion = "1.28.0"
    junitPlatformVersion = "1.12.2"
}

ext.isSecurityDisabled = { ->
    System.getenv('DOCKER_ENABLE_SECURITY') == 'false' ||
    System.getenv('DISABLE_ADDITIONAL_FEATURES') == 'true' ||
    (project.hasProperty('DISABLE_ADDITIONAL_FEATURES') &&
     System.getProperty('DISABLE_ADDITIONAL_FEATURES') == 'true')
}

jar {
    enabled = false
    manifest {
        attributes "Implementation-Title": "Stirling-PDF",
            "Implementation-Version": project.version
    }
}

bootJar {
    enabled = false
}

// Configure main class for the root project
springBoot {
    mainClass = 'stirling.software.SPDF.SPDFApplication'
}

repositories {
    mavenCentral()
    maven { url = 'https://build.shibboleth.net/maven/releases' }
}

allprojects {
    group = 'stirling.software'
    version = '1.4.0'

    configurations.configureEach {
        exclude group: 'commons-logging', module: 'commons-logging'
        exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
    }
}

tasks.register('writeVersion', WriteProperties) {
    destinationFile = layout.projectDirectory.file('app/common/src/main/resources/version.properties')
    println "Writing version.properties to ${destinationFile.get().asFile.path}"
    comment = "${new Date()}"
    property 'version', project.provider { project.version.toString() }
}

subprojects {
    apply plugin: 'java'
    apply plugin: 'java-library'
    apply plugin: 'com.diffplug.spotless'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'jacoco'

    java {
        // 17 is lowest but we support and recommend 21
        sourceCompatibility = JavaVersion.VERSION_17
    }

     if (project.name != "stirling-pdf") {
        bootJar {
            enabled = false
        }
     }

    repositories {
        mavenCentral()
    }

    configurations.configureEach {
        exclude group: 'commons-logging', module: 'commons-logging'
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
        // Exclude vulnerable BouncyCastle version used in tableau
        exclude group: 'org.bouncycastle', module: 'bcpkix-jdk15on'
        exclude group: 'org.bouncycastle', module: 'bcutil-jdk15on'
        exclude group: 'org.bouncycastle', module: 'bcmail-jdk15on'
    }

    dependencyManagement {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
        }
    }

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-actuator'
        implementation 'io.github.pixee:java-security-toolkit:1.2.2'

        //tmp for security bumps
        implementation 'ch.qos.logback:logback-core:1.5.19'
        implementation 'ch.qos.logback:logback-classic:1.5.19'
        compileOnly "org.projectlombok:lombok:$lombokVersion"
        annotationProcessor "org.projectlombok:lombok:$lombokVersion"

        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testRuntimeOnly 'org.mockito:mockito-inline:5.2.0'
        testRuntimeOnly "org.junit.platform:junit-platform-launcher:$junitPlatformVersion"

        testImplementation platform("com.squareup.okhttp3:okhttp-bom:5.1.0")
        testImplementation "com.squareup.okhttp3:mockwebserver"
    }

    tasks.withType(JavaCompile).configureEach {
        options.encoding = "UTF-8"
        dependsOn "spotlessApply"
    }

    compileJava {
        options.compilerArgs << "-parameters"
    }

    test {
        useJUnitPlatform()
        finalizedBy jacocoTestReport
    }

    jacocoTestReport {
        dependsOn test
        reports {
            xml.required.set(true)
            csv.required.set(false)
            html.required.set(true)
        }
    }

    jacocoTestCoverageVerification {
        dependsOn jacocoTestReport
        violationRules {
            rule {
                limit {
                    minimum = 0.0
                }
            }
        }
    }

    tasks.named("processResources") {
        dependsOn(rootProject.tasks.writeVersion)
    }

    if (name == 'stirling-pdf') {
        apply plugin: 'org.springdoc.openapi-gradle-plugin'

        openApi {
            apiDocsUrl = "http://localhost:8080/v1/api-docs"
            outputDir = file("$projectDir")
            outputFileName = "SwaggerDoc.json"
            waitTimeInSeconds = 60 // Increase the wait time to 60 seconds
        }

        tasks.named("forkedSpringBootRun") {
            dependsOn(":common:jar")
            dependsOn(":proprietary:jar")
        }

        tasks.register("copySwaggerDoc", Copy) {
            doNotTrackState("Writes SwaggerDoc.json to project root")
            from(layout.projectDirectory.file("SwaggerDoc.json"))
            into(rootProject.projectDir)
            dependsOn("generateOpenApiDocs")
        }

        tasks.register("cleanSwaggerInBuild", Delete) {
            doNotTrackState("Cleans up SwaggerDoc.json in build directory")
            delete(layout.projectDirectory.file("SwaggerDoc.json"))
            dependsOn("copySwaggerDoc")
        }

        tasks.named("copySwaggerDoc") {
            finalizedBy("cleanSwaggerInBuild")
        }

        tasks.named("generateOpenApiDocs") {
            finalizedBy("copySwaggerDoc")
            doNotTrackState("OpenAPI plugin writes outside build directory")
        }
    }
}

tasks.withType(JavaCompile).configureEach {
    options.encoding = "UTF-8"
    if (!project.hasProperty("noSpotless")) {
        dependsOn "spotlessApply"
    }
}

gradle.taskGraph.whenReady { graph ->
    if (project.hasProperty("noSpotless")) {
        tasks.matching { it.name.startsWith("spotless") }.configureEach {
            enabled = false
        }
    }
}

def allProjects = ((subprojects as Set<Project>) + project) as Set<Project>

licenseReport {
    projects = allProjects
    renderers = [new JsonReportRenderer()]
    allowedLicensesFile = project.layout.projectDirectory.file("app/allowed-licenses.json").asFile
    outputDir = project.layout.buildDirectory.dir("reports/dependency-license").get().asFile.path
    configurations = [ "productionRuntimeClasspath", "runtimeClasspath" ]
}

// Configure the forked spring boot run task to properly delegate to the stirling-pdf module
tasks.named('forkedSpringBootRun') {
    dependsOn ':stirling-pdf:bootRun'
    doFirst {
        println "Delegating forkedSpringBootRun to :stirling-pdf:bootRun"
    }
}

spotless {
    yaml {
        target '*.yml', '*.yaml'
        trimTrailingWhitespace()
        leadingTabsToSpaces()
        endWithNewline()
    }
    format 'gradle', {
        target 'build.gradle', 'settings.gradle', 'gradle/*.gradle', 'gradle/**/*.gradle'
        trimTrailingWhitespace()
        leadingTabsToSpaces()
        endWithNewline()
    }
}

sonar {
    properties {
        property "sonar.projectKey", "Stirling-Tools_Stirling-PDF"
        property "sonar.organization", "stirling-tools"

        property "sonar.exclusions", "**/build-wrapper-dump.json, **/src/main/java/org/apache/**, **/src/main/resources/static/pdfjs/**, **/src/main/resources/static/pdfjs-legacy/**, **/src/main/resources/static/js/thirdParty/**"
        property "sonar.coverage.exclusions", "**/src/main/java/org/apache/**, **/src/main/resources/static/pdfjs/**, **/src/main/resources/static/pdfjs-legacy/**, **/src/main/resources/static/js/thirdParty/**"
        property "sonar.cpd.exclusions", "**/src/main/java/org/apache/**, **/src/main/resources/static/pdfjs/**, **/src/main/resources/static/pdfjs-legacy/**, **/src/main/resources/static/js/thirdParty/**"
    }
}

swaggerhubUpload {
    // dependsOn = generateOpenApiDocs  // Depends on your task generating Swagger docs
    api = "Stirling-PDF"  // The name of your API on SwaggerHub
    owner = "${System.getenv().getOrDefault('SWAGGERHUB_USER', 'Frooodle')}"  // Your SwaggerHub username (or organization name)
    version = project.version  // The version of your API
    inputFile = file("SwaggerDoc.json")  // The path to your Swagger docs
    token = "${System.getenv("SWAGGERHUB_API_KEY")}"  // Your SwaggerHub API key, passed as an environment variable
    oas = "3.0.0"  // The version of the OpenAPI Specification you"re using
}

dependencies {
    implementation project(':stirling-pdf')
    implementation project(':common')
    if (rootProject.ext.isSecurityDisabled()) {
        implementation project(':proprietary')
    }

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly "org.junit.platform:junit-platform-launcher:$junitPlatformVersion"

    testImplementation platform("com.squareup.okhttp3:okhttp-bom:5.1.0")
    testImplementation "com.squareup.okhttp3:mockwebserver"
}

tasks.named("test") {
    useJUnitPlatform()
}

// Make sure all relevant processes depend on writeVersion
processResources.dependsOn(writeVersion)

tasks.register('printVersion') {
    doLast {
        println project.version
    }
}

tasks.named('bootRun') {
    group = 'application'
    description = 'Delegates to :stirling-pdf:bootRun'
    dependsOn ':stirling-pdf:bootRun'

    doFirst {
        println "Delegating to :stirling-pdf:bootRun"
    }
}

tasks.named('build') {
    group = 'build'
    description = 'Delegates to :stirling-pdf:bootJar'
    dependsOn ':stirling-pdf:bootJar', 'buildRestartHelper'

    doFirst {
        println "Delegating to :stirling-pdf:bootJar"
    }
}

// Task to compile RestartHelper.java
tasks.register('compileRestartHelper', JavaCompile) {
    group = 'build'
    description = 'Compiles the RestartHelper utility'

    source = fileTree(dir: 'scripts', include: 'RestartHelper.java')
    classpath = files()
    destinationDirectory = file("${buildDir}/restart-helper-classes")
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

// Task to create restart-helper.jar
tasks.register('buildRestartHelper', Jar) {
    group = 'build'
    description = 'Builds the restart-helper.jar'
    dependsOn 'compileRestartHelper'

    from "${buildDir}/restart-helper-classes"
    archiveFileName = 'restart-helper.jar'
    destinationDirectory = file("${buildDir}/libs")

    manifest {
        attributes 'Main-Class': 'RestartHelper'
    }

    doLast {
        println "restart-helper.jar created at: ${destinationDirectory.get()}/restart-helper.jar"
    }
}
