import groovy.json.JsonSlurper

buildscript {
    repositories {
        gradlePluginPortal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath "io.franzbecker:gradle-lombok:4.0.0"
    }
}
plugins {
    id 'java-library'
    id "de.undercouch.download" version "4.1.1"
    id "com.github.sherter.google-java-format" version "0.9"
    id "io.github.lognet.grpc-spring-boot"

}
grpcSpringBoot {
    grpcSpringBootStarterVersion.set((String)null)
}

apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'maven-publish'
apply plugin: 'signing'
apply plugin: "de.marcphilipp.nexus-publish"
apply plugin: 'io.franzbecker.gradle-lombok'

configurations{
    testImplementation {
        exclude group: 'io.netty', module: 'netty-tcnative-boringssl-static'
        exclude group: 'io.grpc', module: 'grpc-netty-shaded'
    }
}
dependencyManagement {
    imports {
        mavenBom "org.springframework.boot:spring-boot-starter-parent:${springBootVersion}"
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

task generateReleaseNotes(type: JavaExec, group: "documentation") {
    def m = java.util.regex.Pattern.compile("(\\d+\\.\\d+\\.\\d+).*").matcher(version.toString())
    def milestoneLabel = ""
    if (m.find()) {
        milestoneLabel = m.group(1)
    }

    def generator = file("changelog/github-changelog-generator.jar")
    classpath(generator.absolutePath)
    args(
            milestoneLabel
            , "changelog/changelog.md"
            , "--changelog.repository=LogNet/grpc-spring-boot-starter"
    )
    doFirst {
        download {
            src 'https://github.com/spring-io/github-changelog-generator/releases/download/v0.0.8/github-changelog-generator.jar'
            dest generator
            onlyIfModified true
        }
    }
}

lombok {
    version = "${lombokVersion}"
}

def delombokOutputDir = file("$buildDir/delombok")

task delombok(type: io.franzbecker.gradle.lombok.task.DelombokTask) {
    outputs.dir(delombokOutputDir)
    for (srcDir in project.sourceSets.main.java.srcDirs) {
        if(srcDir.exists()) {
            inputs.dir(srcDir)
            args(srcDir, "-d", delombokOutputDir)
        }
    }
    doFirst {
        delombokOutputDir.deleteDir()
    }
}

googleJavaFormat {
    toolVersion = '1.15.0'
    source = delombokOutputDir
    include '**/*.java'
}
tasks.verifyGoogleJavaFormat {
    enabled false
}
tasks.googleJavaFormat {
    dependsOn tasks.delombok
}
task sourceJar(type: Jar) {
    dependsOn(tasks.googleJavaFormat)
    classifier "sources"
    from delombokOutputDir
}
javadoc {
    dependsOn tasks.googleJavaFormat
    source = delombokOutputDir
}
task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier "javadoc"
    from javadoc.destinationDir
}

artifacts {
    archives jar
    archives sourceJar
    archives javadocJar
}
signing {
    sign configurations.archives
}
test {
    useJUnitPlatform {
//        includeTags 'fast'
//        excludeTags 'slow'
    }
}

nexusPublishing {
    clientTimeout = java.time.Duration.ofMinutes(7)
    repositories {
        sonatype()
    }

}
configurations.testImplementation.setCanBeResolved(true)

task testDependencyFatJar(type: org.springframework.boot.gradle.tasks.bundling.BootJar) {
    targetJavaVersion = JavaVersion.VERSION_17
    dependsOn testClasses,classes
    mainClass =  'org.lognet.grpc.demo.DemoApp'
    setClasspath(configurations.testImplementation)
    doFirst {
        classpath sourceSets.getByName("test").java.classesDirectory
        classpath sourceSets.getByName("main").output
    }
    archiveClassifier.convention("bootable-test")
}

jar {
    enabled = true
    archiveClassifier.convention("")


    // generate native config by executing test app in graalvm docker image
    // then grab generated json files and filter to include class from `org.lognet.springboot.grpc` package only
    dependsOn testDependencyFatJar
    File aotDir = new File(buildDir, "native-configs");
    File transformed = new File(aotDir, "transformed")
    transformed.mkdirs()
    from(transformed) {
        into("META-INF/native-image/io.github.lognet/grpc-spring-boot-starter")
        include "*.*"
    }
    doFirst {

        exec {
            commandLine("docker",
                    "run", "--rm",
                    "-v", "${tasks.testDependencyFatJar.archiveFile.get().getAsFile().parent}:/tmp",
                    "-v", "${aotDir}:/out",
                    "findepi/graalvm:java17-native",
                    "java",
                    "-agentlib:native-image-agent=config-output-dir=/out/",
                    "-jar", "/tmp/${tasks.testDependencyFatJar.archiveFileName.get()}",
                    "--auto-close=true",
                    "--spring.cloud.consul.discovery.enabled=false",
                    "--spring.cloud.consul.enabled=false",
                    "--spring.cloud.service-registry.auto-registration.enabled=false"
            )
        }
        new File(transformed, "reflection-config.json").withWriter { w ->
            new File(aotDir, "reflect-config.json").withInputStream { is ->
                def filtered = new JsonSlurper().parse(is)
                        .findAll { it.name.contains("org.lognet.springboot.grpc") }
                def finalJson = new groovy.json.JsonBuilder()
                finalJson.call(filtered)
                finalJson.writeTo(w)
            }
        }
        new File(transformed, "resource-config.json").withWriter { w ->
            new File(aotDir, "resource-config.json").withInputStream { is ->
                def obj = new JsonSlurper().parse(is)

                def filtered = obj.resources.includes
                        .findAll { it.pattern.contains("org/lognet/springboot/grpc") }

                def finalJson = new groovy.json.JsonBuilder()
                finalJson{
                    resources{
                        includes (filtered)
                    }
                }
                finalJson.writeTo(w)

            }
        }

    }

}



bootJar {
    enabled = false
    archiveClassifier.convention('boot')
}
publishing {
    publications {
        mavenJava(MavenPublication) {
            pom {
                name = 'grpc-spring-boot-starter'
                description = 'grpc-spring-boot-starter'
                url = 'https://github.com/LogNet/grpc-spring-boot-starter'

                scm {
                    url = 'https://github.com/LogNet/grpc-spring-boot-starter'
                    connection = 'scm:https://LogNet@github.com/LogNet/grpc-spring-boot-starter.git'
                    developerConnection = 'scm:git://github.com/LogNet/grpc-spring-boot-starter.git'
                }

                licenses {
                    license {
                        name = 'The Apache Software License, Version 2.0'
                        url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                        distribution = 'repo'
                    }
                }

                developers {
                    developer {
                        id = 'jvmlet'
                        name = 'Furer Alexander'
                        email = 'furer.alexander@gmail.com'
                    }
                }

            }

            from components.java


            artifact(sourceJar) {
                classifier = 'sources'
            }
            artifact(javadocJar) {
                classifier = 'javadoc'
            }
        }
    }
}


signing {
    required {
        // signing is required if this is a release version and the artifacts are to be published
        !version.toString().endsWith('-SNAPSHOT') && tasks.withType(PublishToMavenRepository).find {
            gradle.taskGraph.hasTask it
        }
    }
    sign publishing.publications
}


dependencies {
    compileOnly "io.grpc:grpc-netty:${grpcVersion}"
    api "io.grpc:grpc-netty-shaded:${grpcVersion}"
    api "io.grpc:grpc-services:${grpcVersion}"
    api "org.springframework.boot:spring-boot-starter"
    api 'io.netty:netty-tcnative-boringssl-static:2.0.47.Final'

    annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")

    compileOnly("org.springframework.boot:spring-boot-starter-security")
    compileOnly "org.springframework.security:spring-security-oauth2-resource-server"
    compileOnly "org.springframework.security:spring-security-oauth2-jose"
    compileOnly 'org.springframework.boot:spring-boot-starter-validation'
    compileOnly "org.springframework.boot:spring-boot-starter-actuator"
    compileOnly "org.springframework.boot:spring-boot-starter-validation"
    compileOnly 'org.springframework.cloud:spring-cloud-starter-consul-discovery'


    testImplementation "javax.annotation:javax.annotation-api:1.3.2"
    testImplementation "io.grpc:grpc-netty"
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

}


if (null != System.getenv("CI")) {
    compileJava {
        dependsOn(processResources, tasks.googleJavaFormat)
        source googleJavaFormat.source
        include { FileTreeElement e ->
            def included = true
            if (e.name.toLowerCase().endsWith("java")) {
                included = e.file.absolutePath.startsWith(delombokOutputDir.absolutePath)
            }

            return included
        }
    }
}


