import org.apache.tools.ant.taskdefs.condition.Os

plugins {
    id "java"
    id 'maven-publish'
    id "com.github.spotbugs"
    id "jacoco"
    id "com.github.johnrengelman.shadow"
    id "de.undercouch.download"
    id "net.researchgate.release"
}

def packageName = "asyncapi"

configurations {
    balTools
}

allprojects {
    group = 'io.ballerina'
    version = project.version
    apply plugin: 'checkstyle'
    apply plugin: 'maven-publish'

    repositories {
        mavenLocal()

        maven {
            url = 'https://maven.pkg.github.com/ballerina-platform/*'
            credentials {
                username System.getenv("packageUser")
                password System.getenv("packagePAT")
            }
        }

        maven {
            url = 'https://maven.wso2.org/nexus/content/repositories/releases/'
        }
        maven {
            url = 'https://maven.wso2.org/nexus/content/groups/wso2-public/'
        }

        maven {
            url = 'https://maven.wso2.org/nexus/content/repositories/orgballerinalang-1614'
        }

        maven {
            url = 'https://repo.maven.apache.org/maven2'
        }

        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    ext {
        snapshotVersion= '-SNAPSHOT'
        timestampedVersionRegex = '.*-\\d{8}-\\d{6}-\\w.*\$'
    }
}

subprojects {
    // Only apply Java plugin to projects that need it (exclude asyncapi-tool which uses Ballerina plugin)
    if (project.name != 'asyncapi-tool') {
        apply plugin: 'java'
        dependencies {
            implementation "io.apicurio:apicurio-data-models:${apiCurioVersion}"
            implementation "org.apache.logging.log4j:log4j-core:${log4jVersion}"
            implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${jacksonDataformatYamlVersion}"
            implementation "commons-io:commons-io:${commonsIoVersion}"
            implementation "org.ballerinalang:ballerina-lang:${ballerinaLangVersion}"
            implementation "org.ballerinalang:ballerina-parser:${ballerinaLangVersion}"
            implementation "org.ballerinalang:ballerina-cli:${ballerinaLangVersion}"
            implementation "org.ballerinalang:formatter-core:${ballerinaLangVersion}"
            implementation "org.ballerinalang:ballerina-tools-api:${ballerinaLangVersion}"
            implementation "io.ballerina.stdlib:http-native:${stdlibHttpVersion}"
            implementation "org.ballerinalang:language-server-commons:${ballerinaLangVersion}"
            implementation "info.picocli:picocli:${picocliVersion}"
            testImplementation "org.junit.jupiter:junit-jupiter-api:5.6.0"
            testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
            testImplementation "org.testng:testng:${testngVersion}"
        }
    }
}

ext {
    snapshotVersion= '-SNAPSHOT'
    timestampedVersionRegex = '.*-\\d{8}-\\d{6}-\\w.*\$'
}

test {
    useTestNG() {
        suites "src/test/resources/testng.xml"
    }
}

def moduleVersion = project.version.replace("-SNAPSHOT", "")

release {
    // Disable check snapshots temporarily
    failOnPublishNeeded = false
    versionPropertyFile = 'gradle.properties'
    tagTemplate = 'v${version}'
    git {
        // To release from any branch
        requireBranch = "release-${moduleVersion}"
        pushToRemote = 'origin'
    }
}

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

task codeCoverageReport(type: JacocoReport) {
    dependsOn = subprojects.findAll { it.name != 'asyncapi-tool' }.test

    executionData fileTree(project.rootDir.absolutePath).include("**/build/coverage-reports/*.exec")

    subprojects.findAll { it.name != 'asyncapi-tool' }.each {
        sourceSets it.sourceSets.main
    }
    reports {
        xml.required = true
        html.required = true
        csv.required = true
        xml.destination(new File("${buildDir}/reports/jacoco/report.xml"))
        html.destination(new File("${buildDir}/reports/jacoco/report.html"))
        csv.destination(new File("${buildDir}/reports/jacoco/report.csv"))
    }

    onlyIf = {
        true
    }
}

shadowJar {
    configurations = [project.configurations.runtimeClasspath]
    dependencies {
        include(dependency('com.github.jknack:handlebars'))
        include(dependency('org.antlr:antlr4:4.5'))
        include(dependency("io.apicurio:apicurio-data-models:${apiCurioVersion}"))
        include(dependency('com.atlassian.commonmark:commonmark'))
        include(dependency('com.atlassian.commonmark:commonmark-ext-gfm-tables'))
        exclude('META-INF/*.SF')
        exclude('META-INF/*.DSA')
        exclude('META-INF/*.RSA')
    }
}

compileJava {
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath,
        ]
        classpath = files()
    }
}

def artifactCacheParent = file("$project.projectDir/build/cache_parent/")
def artifactLibParent = file("$project.projectDir/build/lib_parent/")
def targetAsyncApiCliJar = file("$project.rootDir/asyncapi-cli/build/libs/asyncapi-cli-${project.version}.jar")
def targetNativeHandlerJar = file("$project.rootDir/native.handler/build/libs/native.handler-${project.version}.jar")

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

task directoryBuild {

    inputs.dir file(project.projectDir)
    doNotTrackState("build needs to run every time")
    doLast {
        copy {
            from targetAsyncApiCliJar
            into file("$artifactLibParent/libs")
        }
        copy {
            from targetNativeHandlerJar
            into file("$artifactLibParent/libs")
        }
    }

    outputs.dir artifactCacheParent
    outputs.dir artifactLibParent
}

task createArtifactZip(type: Zip) {
    destinationDirectory = file("${buildDir}/distributions")
    from directoryBuild
}

directoryBuild.dependsOn ":${packageName}-cli:build"
directoryBuild.dependsOn ":asyncapi-tool:build"
directoryBuild.dependsOn ":compileJava"
directoryBuild.dependsOn ":compileTestJava"
directoryBuild.dependsOn ":test"
directoryBuild.dependsOn ":jar"
directoryBuild.dependsOn ":checkstyleMain"
directoryBuild.dependsOn ":checkstyleTest"
directoryBuild.dependsOn ":spotbugsMain"
directoryBuild.dependsOn ":spotbugsTest"

directoryBuild.dependsOn ":native.handler:compileJava"
directoryBuild.dependsOn ":native.handler:compileTestJava"
directoryBuild.dependsOn ":native.handler:jar"
directoryBuild.dependsOn ":native.handler:checkstyleMain"
directoryBuild.dependsOn ":native.handler:checkstyleTest"
directoryBuild.dependsOn ":native.handler:test"
directoryBuild.dependsOn ":native.handler:java-wrapper:compileJava"
directoryBuild.dependsOn ":native.handler:java-wrapper:compileTestJava"
directoryBuild.dependsOn ":native.handler:java-wrapper:jar"
directoryBuild.dependsOn ":native.handler:java-wrapper:checkstyleMain"
directoryBuild.dependsOn ":native.handler:java-wrapper:checkstyleTest"
directoryBuild.dependsOn ":native.handler:java-wrapper:test"
directoryBuild.dependsOn ":native.handler:java-wrapper:processTestResources"
directoryBuild.dependsOn ":checkstyle:compileTestJava"
directoryBuild.dependsOn ":checkstyle:checkstyleMain"
directoryBuild.dependsOn ":checkstyle:checkstyleTest"
directoryBuild.dependsOn ":checkstyle:test"
directoryBuild.dependsOn ":checkstyle:processTestResources"

directoryBuild.dependsOn ":asyncapi-tool:jBallerinaPack"
directoryBuild.dependsOn ":asyncapi-tool:generatePomFileForMavenPublication"
directoryBuild.dependsOn ":asyncapi-tool:createArtifactZip"

build.dependsOn directoryBuild
build.dependsOn ":asyncapi-tool:build"

publish.dependsOn build
