plugins {
    id 'java'
    id 'application'
    id 'com.google.protobuf' version '0.9.5'
    id 'io.freefair.lombok' version '8.13.1'
    id 'com.gradleup.shadow' version '8.3.6'
    id 'me.champeau.jmh' version '0.7.3'
}

group = 'io.ringbroker'
version = '0.1.0-SNAPSHOT'

/* ----------  JVM  ---------- */
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
    withJavadocJar()
    withSourcesJar()
}

application {
    // for Gradle 7.1+ use:
    mainClass.set("io.ringbroker.BrokerMain")
}

/* ----------  Repos & Versions ---------- */
repositories { mavenCentral() }

ext {
    grpcVersion = '1.72.0'
    protobufVersion = '3.25.7'
    jacksonVersion = '2.19.0'
    picocliVersion = '4.7.7'
    nettyVersion = '4.2.1.Final'
    jmhVersion = '1.37'
    slf4jVersion = '2.0.17'
    jupiterVersion = '5.12.2'
    junitPlatformVersion = '1.12.2'  // Added matching platform version
    annotationVersion = '1.3.2'
}

/* ----------  Dependencies ---------- */
dependencies {
    // gRPC and Protobuf
    implementation "io.grpc:grpc-netty-shaded:$grpcVersion"
    implementation "io.grpc:grpc-stub:$grpcVersion"
    implementation "io.grpc:grpc-protobuf:$grpcVersion"
    implementation "com.google.protobuf:protobuf-java:$protobufVersion"
    implementation "io.netty:netty-all:$nettyVersion"

    // Lombok (enabled via plugin)
    compileOnly "org.projectlombok:lombok"
    annotationProcessor "org.projectlombok:lombok"

    // Jackson YAML for config parsing
    implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
    implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jacksonVersion"

    // Picocli CLI support
    implementation "info.picocli:picocli:$picocliVersion"
    annotationProcessor "info.picocli:picocli-codegen:$picocliVersion"

    // SLF4J API (you can choose a backend like logback)
    implementation "org.slf4j:slf4j-api:$slf4jVersion"
    runtimeOnly "org.slf4j:slf4j-simple:$slf4jVersion"

    // JUnit 5
    testImplementation "org.junit.jupiter:junit-jupiter:$jupiterVersion"
    testImplementation "org.junit.platform:junit-platform-launcher:$junitPlatformVersion"

    compileOnly "javax.annotation:javax.annotation-api:$annotationVersion"

    // JMH dependencies
    jmh "org.openjdk.jmh:jmh-core:${jmhVersion}"
    jmh "org.openjdk.jmh:jmh-generator-annprocess:${jmhVersion}"
}

/* ----------  Protobuf / gRPC code‑gen ---------- */
protobuf {
    protoc { artifact = "com.google.protobuf:protoc:${protobufVersion}" }
    plugins {
        grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
    }
    generateProtoTasks {
        all().each { task ->
            task.plugins { grpc {} }
        }
    }
}

/* ----------  Application entry‑point ---------- */
application {
    mainClass = 'io.ringbroker.BrokerMain'
}

/* ----------  Tests ---------- */
test {
    useJUnitPlatform()
    jvmArgs '--enable-preview'
}

/* ----------  Jar manifest ---------- */
jar {
    manifest {
        attributes(
                'Implementation-Title': 'RingBroker',
                'Implementation-Version': version,
                'Main-Class': application.mainClass
        )
    }
}

/* ----------  JMH Configuration ---------- */
jmh {
    includes = ['.*Benchmark.*']  // Include classes with "Benchmark" in their name
    resultFormat = 'JSON'         // Output format for results
    resultsFile = project.file("${project.buildDir}/reports/jmh/results.json")
    timeOnIteration = '1s'        // Time per iteration
    warmupIterations = 2          // Number of warmup iterations
    iterations = 5                // Number of measurement iterations
    fork = 2                      // Number of forks
    failOnError = true            // Fail build on errors during benchmarking
    forceGC = true                // Force GC between iterations
    jvmArgsAppend = ['--enable-preview'] // Add any JVM args needed for your project
}

