/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 java.util.concurrent.TimeUnit

//import com.github.spotbugs.snom.SpotBugsTask

buildscript {
    repositories {
        maven {
            url "https://maven.aliyun.com/repository/public"
        }

        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }

    dependencies {
        classpath "gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.7.1"
    }
}

allprojects {
    apply plugin: 'java'
    apply plugin: "eclipse"
    apply plugin: "idea"
    apply plugin: "project-reports"
    apply plugin: "maven-publish"
    apply plugin: "com.github.spotbugs"
    apply plugin: "project-reports"
    apply plugin: "jacoco"
    apply plugin: "pmd"
    apply plugin: "java-library"
    apply plugin: 'signing'

//    print(project)
//    if (project.findProperty("jdk") == "1.7") {
//        sourceCompatibility = 1.7
//        targetCompatibility = 1.7
//        version = version + "-jdk7"
//    } else {
//        sourceCompatibility = 1.8
//        targetCompatibility = 1.8
//        version = version + "-jdk8"
//    }
    [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8'

    compileJava.options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"

    clean.doFirst {
        delete 'build'
        delete 'dist'
        delete 'out'
    }

    if ((project.findProperty("snapshot") instanceof String) && (Boolean.valueOf(project.property("snapshot")))) {
        version = version + "-SNAPSHOT"
    }
}

task tar(type: Tar) {
    extension = 'tar.gz'
    compression = Compression.GZIP
    archiveFileName = project.name + '_' + project.version + '.' + extension
    destinationDirectory = new File(projectDir, 'build')
    into('/') {
        from 'dist'
    }
}


task zip(type: Zip) {
    extension = 'zip'
    archiveFileName = project.name + '.' + project.version + '.' + extension
    destinationDirectory = new File(projectDir, 'build')
    into('/') {
        from 'dist'
    }
}

subprojects {

    List fastjson = [
            "com.alibaba:fastjson:1.2.71"
    ]

    List jackson = [
            'com.fasterxml.jackson.core:jackson-databind:2.11.0',
            'com.fasterxml.jackson.core:jackson-core:2.11.0',
            'com.fasterxml.jackson.core:jackson-annotations:2.11.0'
    ]

    List apache_commons = [
            "org.apache.commons:commons-lang3:3.6",
            "org.apache.commons:commons-collections4:4.1"
    ]

    List httpclient = [
            "org.apache.httpcomponents:httpclient:4.5.2"
    ]

    List guava = [
            "com.google.guava:guava:29.0-jre"
    ]

    List netty = [
            "io.netty:netty-all:4.1.49.Final"
    ]

    List junit = [
            "junit:junit:4.12"
    ]

    List log = [
            "org.slf4j:slf4j-api:1.7.30"
    ]

    List log4j2 = [
            "org.apache.logging.log4j:log4j-api:2.13.3",
            "org.apache.logging.log4j:log4j-core:2.13.3",
            "org.apache.logging.log4j:log4j-slf4j-impl:2.13.3",
            "org.apache.logging.log4j:log4j-web:2.13.3",
            "com.lmax:disruptor:3.4.2"
    ]

    List common = [
            "commons-io:commons-io:2.4",
            "org.apache.commons:commons-text:1.9"
    ]

    List assertj = [
            "org.assertj:assertj-core:2.6.0"
    ]

    List mock = [
            "org.mockito:mockito-core:2.23.0",
            "org.powermock:powermock-module-junit4:2.0.2",
            "org.powermock:powermock-api-mockito2:2.0.2",
    ]

    dependencies {
        implementation apache_commons, guava, log, log4j2, fastjson, jackson, common, httpclient, netty
        testImplementation apache_commons, guava, log, log4j2, fastjson, jackson, common, junit, assertj, mock, httpclient, netty
        spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.11.0'
        spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.7'
    }

    sourceSets {
        main {
            java.srcDirs = ['src/main/java']
        }

        test {
            java.srcDirs = ['src/test/java']
        }
    }

    clean.doFirst {
        delete 'build'
        delete 'dist'
    }

    jacoco {
        toolVersion = "0.8.6"
    }

    jacocoTestReport {
        reports {
            xml.enabled true
            csv.enabled false
            html.enabled false
        }
    }

//    checkstyle {
//        toolVersion = "8.32"
//        ignoreFailures = true
//        sourceSets = [sourceSets.main]
//        configFile = '../style/codeStyle.xml' as File
//        showViolations true
//    }
//
//    tasks.withType(Checkstyle) {
//        reports {
//            xml.enabled false
//            html.enabled true
//        }
//    }
//
//    sourceSets {
//        main {
//            java {
//                srcDir 'src/main/java'
//            }
//
//            resources {
//                srcDir 'src/main/resources'
//            }
//
//        }
//
//        test {
//            java {
//                srcDir 'src/test/java'
//            }
//
//            resources {
//                srcDir 'src/test/resources'
//            }
//
//        }
//    }

    spotbugs {
        //toolVersion = '4.2.3'
        ignoreFailures = true
        showProgress = true
        showStackTraces = true
        //reportLevel = 'default'
        effort = 'default'
        //visitors = [ 'FindSqlInjection', 'SwitchFallthrough' ]
        //omitVisitors = [ 'FindNonShortCircuit' ]
        reportsDir = file("$buildDir/reports/spotbugs")
        //includeFilter = file('spotbugs-include.xml')
        //excludeFilter = file('spotbugs-exclude.xml')
        //onlyAnalyze = ['org/apache/eventmesh/**']
        projectName = rootProject.name
        release = version
        extraArgs = ['-nested:false']
        //jvmArgs = [ '-Duser.language=zh' ]
        maxHeapSize = '256m'

    }

    spotbugsMain {

        reports {
            xml.enabled = false
            html {
                enabled = true
                destination = file("$buildDir/reports/spotbugs/main/spotbugs.html")
                stylesheet = 'fancy-hist.xsl'
            }
        }
    }

    spotbugsTest {
        reports {
            xml.enabled = false
            html {
                enabled = true
                destination = file("$buildDir/reports/spotbugs/test/spotbugs.html")
                stylesheet = 'fancy-hist.xsl'
            }
        }
    }

//        tasks.withType(Pmd) {
//            reports {
//                xml.enabled = false
//                html.enabled = true
//            }
//        }


    pmd {
        consoleOutput = true
        toolVersion = "6.23.0"
        rulesMinimumPriority = 5
        ruleSets = ["category/java/errorprone.xml", "category/java/bestpractices.xml"]
        ignoreFailures = true
    }

    jar {
        manifest {
            attributes("Specification-Version": project.version,
                    "Specification-Vendor": "WeBank, Inc.",
                    "Specification-Title": project.name,
                    "Implementation-Version": project.version,
                    "Implementation-Vendor": "WeBank, Inc.",
                    "Implementation-Title": project.name,
                    "Build-Jdk": project.findProperty("jdk")
            )
        }
    }

    task dist(dependsOn: ['jar']) {
        doFirst {
            new File(projectDir, '../dist/bin').mkdirs()
            new File(projectDir, '../dist/apps').mkdirs()
            new File(projectDir, '../dist/conf').mkdirs()
            new File(projectDir, '../dist/lib').mkdirs()
        }

        doLast {
            copy {
                into('../dist/apps/')
                from project.jar.getArchivePath()
                exclude 'eventmesh-common*.jar'
                exclude 'eventmesh-connector-api*.jar'
                exclude 'eventmesh-starter*.jar'
                exclude 'eventmesh-test*.jar'
                exclude 'eventmesh-sdk*.jar'
            }
            copy {
                into '../dist/lib'
                from project.configurations.runtimeClasspath
                exclude '**/*.properties*'
                exclude '**/*testng*.jar'
                exclude '**/*powermock*.jar'
                exclude '**/*mockito*.jar'
                exclude '**/*junit*.jar'
                exclude '**/*jacoco*.jar'
                exclude '**/*log4j2.xml*'
                exclude '**/spring-boot-devtools*.jar'
                exclude '**/mumble-sdk-test*.jar'
                exclude '*connector-rocketmq*.jar'
                exclude 'eventmesh-runtime*.jar'
//                exclude '*log4j*.jar'
                exclude 'commons-collections-3.2.2.jar'
            }

            copy {
                into '../dist/bin'
                from '../eventmesh-runtime/bin'
            }

            copy {
                into '../dist/conf'
                from '../eventmesh-runtime/conf'
            }
        }
    }

    javadoc {
        source = sourceSets.main.java
        //classpath = configurations.implementation
        destinationDir = reporting.file("javadoc")
    }

    task packageJavadoc(type: Jar, dependsOn: ['javadoc']) {
        from project.javadoc.destinationDir
        classifier = 'javadoc'
    }

    task packageSources(type: Jar) {
        from project.sourceSets.main.allSource
        classifier = 'sources'  // either here or in artifacts block
    }

    artifacts {
        archives jar
        archives packageJavadoc
        archives packageSources
    }

    if (!Boolean.valueOf(signEnabled)) {
        tasks.whenTaskAdded {task ->
            if(task.name.contains("sign")) {
                task.enabled = false
            }
        }
    }

    repositories {
        maven { url "https://maven.aliyun.com/repository/public" }
        mavenCentral()
        mavenLocal()
    }


    configurations.all {
        resolutionStrategy.cacheChangingModulesFor 0, TimeUnit.SECONDS
        resolutionStrategy.cacheDynamicVersionsFor 0, TimeUnit.SECONDS
    }

    publishing {
        publications {
            mavenJava(MavenPublication) {
                from components.java
                artifact packageSources
                artifact packageJavadoc
                versionMapping {
                    usage('java-api') {
                        fromResolutionOf('runtimeClasspath')
                    }
                    usage('java-runtime') {
                        fromResolutionResult()
                    }
                }
                pom {
                    name = 'EventMesh'
                    description = 'Apache EventMesh'
                    url = 'https://github.com/apache/incubator-eventmesh'
                    licenses {
                        license {
                            name = 'The Apache License, Version 2.0'
                            url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                        }
                    }
                    developers {
                        developer {
                            id = 'Apache EventMesh(incubating)'
                            name = 'Apache EventMesh(incubating) of ASF'
                            url = 'https://eventmesh.apache.org/'
                        }
                    }
                    scm {
                        connection = 'scm:git:git@github.com:apache/incubator-eventmesh.git'
                        developerConnection = 'scm:git:git@github.com:apache/incubator-eventmesh.git'
                        url = 'https://github.com/apache/incubator-eventmesh'
                    }
                }
            }
        }
        repositories {
            maven {
                def releasesRepoUrl = 'https://repository.apache.org/content/repositories/releases/'
                def snapshotsRepoUrl = 'https://repository.apache.org/content/repositories/snapshots/'
                url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
                credentials {
                    username apacheUserName
                    password apachePassWord
                }

            }
        }
    }

    signing {
        sign publishing.publications.mavenJava
    }

}

