/*
 * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

plugins {
    id "java"
    id "com.github.johnrengelman.shadow"
    id "jacoco"
    id "checkstyle"
}

configurations.all {
    resolutionStrategy.preferProjectModules()
}

dependencies {
    checkstyle project(':checkstyle')
    checkstyle "com.puppycrawl.tools:checkstyle:${project.checkstylePluginVersion}"

    implementation project(':graphql-schema-file-generator')
    implementation project(':graphql-code-generator')
    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 "info.picocli:picocli:${picocliVersion}"
    testImplementation "org.testng:testng:${testngVersion}"
    testImplementation "org.apache.commons:commons-lang3:${commonsLang3Version}"
    implementation "commons-io:commons-io:${commonsIoVersion}"
    implementation "commons-logging:commons-logging:${commonsLoggingVersion}"
    implementation "org.yaml:snakeyaml:${snakeYamlVersion}"
    implementation "com.graphql-java:graphql-java:${graphqlJavaVersion}"
    implementation "org.json:json:${orgJsonVersion}"
    dist "io.ballerina.stdlib:graphql-commons:${stdlibGraphqlVersion}"

    jbalTools ("org.ballerinalang:jballerina-tools:${ballerinaLangVersion}") {
        transitive = false
    }
}

tasks.register('copyAllDependencies', Copy) {
    //referring to the 'compileClasspath' configuration
    from configurations.compileClasspath
    into "$rootDir/graphql-tool/build/libs"
}

def excludePattern = '**/module-info.java'
tasks.withType(Checkstyle) {
    exclude excludePattern
}

checkstyle {
    toolVersion "${project.checkstylePluginVersion}"
    configFile rootProject.file("config/checkstyle/build/checkstyle.xml")
    configProperties = ["suppressionFile" : file("${rootDir}/config/checkstyle/build/suppressions.xml")]
}

checkstyleMain.dependsOn(":checkstyle:downloadCheckstyleRuleFiles")
checkstyleTest.dependsOn(":checkstyle:downloadCheckstyleRuleFiles")

def bDistribution = file("$project.buildDir/extracted-distribution/jballerina-tools-${ballerinaLangVersion}")
task jBallerinaPack {
    doLast {
        configurations.jbalTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->
            copy {
                from project.zipTree(artifact.getFile())
                into new File(project.buildDir, "extracted-distribution/")
            }
        }
    }
    outputs.dir bDistribution
}

task unpackStdLibs() {
    dependsOn(jBallerinaPack)
    doLast {
        configurations.ballerinaStdLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->
            copy {
                from project.zipTree(artifact.getFile())
                into new File("${project.buildDir}/extracted-distribution/" + artifact.name + "-zip")
            }
        }
    }
}

task copyStdlibs(type: Copy) {
    dependsOn(unpackStdLibs)
    def ballerinaDist = "$project.buildDir/extracted-distribution/jballerina-tools-${ballerinaLangVersion}"
    into ballerinaDist

    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    /* Standard Libraries */
    configurations.ballerinaStdLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->
        def artifactExtractedPath = "${project.buildDir}/extracted-distribution/" + artifact.name + "-zip"
        into("repo/bala") {
            from "${artifactExtractedPath}/bala/"
        }
        into("repo/cache") {
            from "${artifactExtractedPath}/cache"
        }
    }
}

task copyJar(type: Copy) {
    from "$project.rootDir/graphql-schema-file-generator/build/libs/graphql-schema-file-generator-${version}.jar"
    from "$project.rootDir/graphql-code-generator/build/libs/graphql-code-generator-${version}.jar"
    from "$project.buildDir/libs/graphql-cli-${version}.jar"
    into "$project.buildDir/extracted-distribution/jballerina-tools-${ballerinaLangVersion}/bre/lib"
}

jar {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    dependsOn configurations.dist
    from { configurations.dist.collect { it.isDirectory() ? it : zipTree(it) } } {
        exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
    }

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

def disableGroups = ""

task initializeVariables {
    if (project.hasProperty("disable")) {
        disableGroups = project.findProperty("disable")
    }
}

test {
    systemProperties = [ "target.dir": "$project.buildDir",
                         "distributions.dir": bDistribution,
                         "ballerina.home": bDistribution,
                         "ballerina.version": "jballerina-tools-${ballerinaLangVersion}"
    ]

    testLogging {
        showStackTraces = true
        showStandardStreams = true
    }

    dependsOn {
        copyStdlibs
        initializeVariables
    }

    useTestNG() {
        excludeGroups(disableGroups)
        suites "src/test/resources/testng.xml"
    }
    finalizedBy jacocoTestReport
}

jacoco {
    toolVersion = "0.8.10"
    reportsDirectory = file("$rootProject.projectDir/build/reports/jacoco")
}

jacocoTestReport {
    dependsOn test // tests are required to run before generating the report
    def classFiles = new File("${rootDir}/graphql-schema-file-generator/build/classes/java/main/io/ballerina/graphql/schema")
    def codeGenFiles = new File("${rootDir}/graphql-code-generator/build/classes/java/main/io/ballerina/graphql" +
            "/generator")
    additionalClassDirs(classFiles)
    additionalClassDirs(codeGenFiles)
    reports {
        xml.required = true
    }
}

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

def packageName = "graphql"

jBallerinaPack.dependsOn ":${packageName}-schema-file-generator:build"
jBallerinaPack.dependsOn ":${packageName}-code-generator:build"
unpackStdLibs.dependsOn jBallerinaPack
copyStdlibs.dependsOn unpackStdLibs
shadowJar.dependsOn copyStdlibs
copyJar.dependsOn shadowJar
copyJar.dependsOn jar
copyJar.dependsOn copyAllDependencies
test.dependsOn copyJar
jacocoTestReport.dependsOn test

build.dependsOn(jacocoTestReport)
