/*
 * Copyright (c) 2020, 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.
 *
 */

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

plugins {
    id 'io.ballerina.plugin'
}

description = 'Ballerina - gRPC Ballerina Generator'

def packageName = "grpc"
def packageOrg = "ballerina"
def tomlVersion = stripBallerinaExtensionVersion("${project.version}")
def ballerinaTomlFilePlaceHolder = new File("${project.rootDir}/build-config/resources/Ballerina.toml")
def compilerPluginTomlFilePlaceHolder = new File("${project.rootDir}/build-config/resources/CompilerPlugin.toml")
def ballerinaTomlFile = new File("$project.projectDir/Ballerina.toml")
def compilerPluginTomlFile = new File("$project.projectDir/CompilerPlugin.toml")
def artifactLibParent = file("$project.projectDir/build/lib_parent/")
// external jar file which need to pack to distribution
def externalGoogleProtosCommonJar = file("$project.projectDir/lib/proto-google-common-protos-${protoGoogleCommonsVersion}.jar")
def externalProtobufJavaJar = file("$project.projectDir/lib/protobuf-java-${protobufJavaVersion}.jar")
def targetNativeJar = file("$project.rootDir/native/build/libs/${packageName}-native-${project.version}.jar")

def stripBallerinaExtensionVersion(String extVersion) {
    if (extVersion.matches(project.ext.timestampedVersionRegex)) {
        def splitVersion = extVersion.split('-')
        if (splitVersion.length > 3) {
            def strippedValues = splitVersion[0..-4]
            return strippedValues.join('-')
        } else {
            return extVersion
        }
    } else {
        return extVersion.replace("${project.ext.snapshotVersion}", "")
    }
}

ballerina {
    packageOrganization = packageOrg
    module = packageName
    langVersion = ballerinaLangVersion
}

configurations {
    externalJars
}

dependencies {

    externalJars(group: 'io.ballerina.stdlib', name: 'http-native', version: "${stdlibHttpVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-common', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-buffer', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-transport', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-resolver', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-handler', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-codec-http', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-codec', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-handler-proxy', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-codec-http2', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-transport-native-unix-common', version: "${nettyVersion}") {
        transitive = false
    }
    externalJars(group: 'commons-pool.wso2', name: 'commons-pool', version: "${wso2CommonsPoolVersion}") {
        transitive = false
    }
    externalJars(group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: "${bouncycastleVersion}") {
        transitive = false
    }
    externalJars(group: 'org.bouncycastle', name: 'bcpkix-jdk18on', version: "${bouncycastleVersion}") {
        transitive = false
    }
    externalJars(group: 'org.bouncycastle', name: 'bcutil-jdk18on', version: "${bouncycastleVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-tcnative-classes', version: "${nettyTcnativeVersion}") {
        transitive = false
    }
    externalJars(group: 'com.google.protobuf', name: 'protobuf-java', version: "${protobufJavaVersion}") {
        transitive = false
    }
    externalJars(group: 'info.picocli', name: 'picocli', version: "${picocliVersion}") {
        transitive = false
    }
    externalJars(group: 'com.google.api.grpc', name: 'proto-google-common-protos', version: "${protoGoogleCommonsVersion}") {
        transitive = false
    }
    externalJars(group: 'org.ballerinalang', name: 'ballerina-cli', version: "${ballerinaLangVersion}") {
        transitive = false
    }
    externalJars(group: 'org.wso2.orbit.org.antlr', name: 'antlr4-runtime', version: "${wso2OrbitAntlrVersion}") {
        transitive = false
    }
    externalJars(group: 'org.ballerinalang', name: 'formatter-core', version: "${ballerinaLangVersion}") {
        transitive = false
    }
    externalJars(group: 'org.ballerinalang', name: 'ballerina-parser', version: "${ballerinaLangVersion}") {
        transitive = false
    }
    externalJars(group: 'io.netty', name: 'netty-tcnative-boringssl-static', version: "${nettyTcnativeVersion}") {
        transitive = false
    }
    externalJars 'io.netty:netty-tcnative-boringssl-static::windows-x86_64'
    externalJars 'io.netty:netty-tcnative-boringssl-static::linux-aarch_64'
    externalJars 'io.netty:netty-tcnative-boringssl-static::linux-x86_64'
    externalJars 'io.netty:netty-tcnative-boringssl-static::osx-aarch_64'
    externalJars 'io.netty:netty-tcnative-boringssl-static::osx-x86_64'
}

task updateTomlFiles {
    doLast {
        def stdlibHttpVersion = stripBallerinaExtensionVersion("${project.stdlibHttpVersion}")
        def newBallerinaToml = ballerinaTomlFilePlaceHolder.text.replace("@project.version@", project.version)
        newBallerinaToml = newBallerinaToml.replace("@toml.version@", tomlVersion)
        newBallerinaToml = newBallerinaToml.replace("@http.native.version@", project.stdlibHttpVersion)
        newBallerinaToml = newBallerinaToml.replace("@antlr.version@", project.wso2OrbitAntlrVersion)
        newBallerinaToml = newBallerinaToml.replace("@protobuf.java.version@", project.protobufJavaVersion)
        newBallerinaToml = newBallerinaToml.replace("@proto.google.commons.version@", project.protoGoogleCommonsVersion)
        newBallerinaToml = newBallerinaToml.replace("@ballerinalang.version@", ballerinaLangVersion)
        newBallerinaToml = newBallerinaToml.replace("@netty.version@", project.nettyVersion)
        newBallerinaToml = newBallerinaToml.replace("@nettytcnative.version@", project.nettyTcnativeVersion)
        newBallerinaToml = newBallerinaToml.replace("@commons.pool.version@", project.wso2CommonsPoolVersion)
        newBallerinaToml = newBallerinaToml.replace("@bouncy.castle.version@", project.bouncycastleVersion)
        newBallerinaToml = newBallerinaToml.replace("@http.version@", stdlibHttpVersion)
        ballerinaTomlFile.text = newBallerinaToml

        def newCompilerPluginToml = compilerPluginTomlFilePlaceHolder.text.replace("@project.version@", project.version)
        compilerPluginTomlFile.text = newCompilerPluginToml
    }
}

task commitTomlFiles {
    doLast {
        project.exec {
            ignoreExitValue true
            if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                commandLine 'cmd', '/c', "git commit -m \"[Automated] Update the native jar versions\" Ballerina.toml Dependencies.toml CompilerPlugin.toml"
            } else {
                commandLine 'sh', '-c', "git commit -m '[Automated] Update the native jar versions' Ballerina.toml Dependencies.toml CompilerPlugin.toml"
            }
        }
    }
}

task copyExternalJars {
    doLast {
        copy {
            from externalProtobufJavaJar
            into file("$artifactLibParent/libs")
        }
        copy {
            from targetNativeJar
            into file("$artifactLibParent/libs")
        }
        copy {
            from externalGoogleProtosCommonJar
            into file("$artifactLibParent/libs")
        }
    }
}

publishing {
    publications {
        maven(MavenPublication) {
            artifact source: createArtifactZip, extension: 'zip'
        }
    }

    repositories {
        maven {
            name = "GitHubPackages"
            url = uri("https://maven.pkg.github.com/ballerina-platform/module-${packageOrg}-${packageName}")
            credentials {
                username = System.getenv("publishUser")
                password = System.getenv("publishPAT")
            }
        }
    }
}

task startLdapServer() {
    doLast {
        if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
            def stdOut = new ByteArrayOutputStream()
            exec {
                commandLine 'sh', '-c', "docker ps --filter name=openldap-server"
                standardOutput = stdOut
            }
            if (!stdOut.toString().contains("openldap-server")) {
                println "Starting LDAP server."
                exec {
                    commandLine 'sh', '-c', "docker compose -f tests/resources/openldap/compose.yml up -d"
                    standardOutput = stdOut
                }
                println stdOut.toString()
                sleep(5 * 1000)
            } else {
                println "LDAP server is already running."
            }
        }
    }
}

updateTomlFiles.dependsOn copyStdlibs

build.dependsOn "generatePomFileForMavenPublication"
build.dependsOn ":${packageName}-native:build"
build.dependsOn ":${packageName}-native:test"
build.dependsOn ":${packageName}-test-utils:build"
build.dependsOn ":${packageName}-compiler-plugin:build"
test.dependsOn ":${packageName}-native:build"
test.dependsOn ":${packageName}-native:test"
test.dependsOn ":${packageName}-test-utils:build"
test.dependsOn ":${packageName}-compiler-plugin:build"
test.dependsOn startLdapServer
build.finalizedBy ":${packageName}-ballerina-tests:build"

publishToMavenLocal.dependsOn copyExternalJars
publish.dependsOn copyExternalJars
publishToMavenLocal.dependsOn build
publish.dependsOn build
