/*
 * 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.
 */

// Following Gradle best practices to keep build logic organized

// ----------------------------------------------------------------------------
// source sets for main and test sources
sourceSets {
    main {
        java {
            srcDir 'src'
        }
    }
    test {
        java {
            srcDir 'test'
            // see functionalTests.gradle for these files
            exclude '**/test/TestClient.java'
            exclude '**/test/TestServer.java'
            exclude '**/test/TestNonblockingServer.java'
            exclude '**/test/TestTServletServer.java'
        }
        resources {
            srcDir 'test/resources'
            include 'log4j.properties'
        }
    }
}

// ----------------------------------------------------------------------------
// Compiler configuration details

// These two properties are still needed on JDK8, and possibly used directly by
// plugins. However, the '--release' option added below makes these two
// properties redundant when building with JDK9 or later.
sourceCompatibility = '1.8'
targetCompatibility = '1.8'

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
    options.debug = true
    options.deprecation = true
    // the following is to build with Java 8 specifications, even when building with JDK9 or later
    if (JavaVersion.current() > JavaVersion.VERSION_1_8) {
        options.compilerArgs.addAll(['--release', '8'])
    }
    // options.compilerArgs.addAll('-Xlint:unchecked')
}

// ----------------------------------------------------------------------------
// Jar packaging details
processResources {
    into('META-INF') {
        from "$thriftRoot/LICENSE"
        from "$thriftRoot/NOTICE"
        rename('(.+)', '$1.txt')
    }
}

jar {
    project.test.dependsOn it
    manifest {
        attributes([
            "Implementation-Version": "${project.version}",
            "Automatic-Module-Name": "${project.group}",
            "Bundle-ManifestVersion": "2",
            "Bundle-SymbolicName": "${project.group}",
            "Bundle-Name": "Apache Thrift",
            "Bundle-Version": "${project.version}",
            "Bundle-Description": "Apache Thrift library",
            "Bundle-License": "${project.license}",
            "Bundle-ActivationPolicy": "lazy",
            "Export-Package": "${project.group}.async;uses:=\"${project.group}.protocol,${project.group}.transport,org.slf4j,${project.group}\";version=\"${version}\",${project.group}.protocol;uses:=\"${project.group}.transport,${project.group},${project.group}.scheme\";version=\"${version}\",${project.group}.server;uses:=\"${project.group}.transport,${project.group}.protocol,${project.group},org.slf4j,javax.servlet,javax.servlet.http\";version=\"${version}\",${project.group}.transport;uses:=\"${project.group}.protocol,${project.group},org.apache.http.client,org.apache.http.params,org.apache.http.entity,org.apache.http.client.methods,org.apache.http,org.slf4j,javax.net.ssl,javax.net,javax.security.sasl,javax.security.auth.callback\";version=\"${version}\",${project.group};uses:=\"${project.group}.protocol,${project.group}.async,${project.group}.server,${project.group}.transport,org.slf4j,org.apache.log4j,${project.group}.scheme\";version=\"${version}\",${project.group}.meta_data;uses:=\"${project.group}\";version=\"${version}\",${project.group}.scheme;uses:=\"${project.group}.protocol,${project.group}\";version=\"${version}\",${project.group}.annotation;version=\"${version}\"",
            "Import-Package": "javax.net,javax.net.ssl,javax.security.auth.callback,javax.security.sasl,javax.servlet;resolution:=optional,javax.servlet.http;resolution:=optional,org.slf4j;resolution:=optional;version=\"[1.4,2)\",org.apache.http.client;resolution:=optional,org.apache.http.params;resolution:=optional,org.apache.http.entity;resolution:=optional,org.apache.http.client.methods;resolution:=optional,org.apache.http;resolution:=optional"
        ])
    }
}
