/*
 * 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
// ----------------------------------------------------------------------------
// Compiler configuration details

// We are using Java 17 toolchain to compile.
// This enables decoupling from the Java version that gradle runs, from
// the actual JDK version for the project. For more details, see
// https://docs.gradle.org/current/userguide/toolchains.html
//
// The '--release' option added below makes sure that even if we are using
// the toolchain version > 11, the final artifact is at version 11. There is
// also a runtime CI that's based on Java 11 to ensure that.
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

tasks.withType(JavaCompile).configureEach {
    options.encoding = 'UTF-8'
    options.debug = true
    options.deprecation = true
    // the following is to build with Java 11 specifications, even when building with later JDK
    options.release = 11
    options.compilerArgs += [
            '-Werror',
            '-Xlint:deprecation',
            '-Xlint:cast',
            '-Xlint:empty',
            '-Xlint:fallthrough',
            '-Xlint:finally',
            '-Xlint:overrides',
            // we can't enable -Xlint:unchecked just yet
    ]
}

tasks.withType(Javadoc) {
    failOnError false
    options.addStringOption('Xdoclint:none', '-quiet')
    options.addStringOption('encoding', 'UTF-8')
    options.addStringOption('charSet', 'UTF-8')
}

// ----------------------------------------------------------------------------
// 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=\"${project.version}\",${project.group}.protocol;uses:=\"${project.group}.transport,${project.group},${project.group}.scheme\";version=\"${project.version}\",${project.group}.server;uses:=\"${project.group}.transport,${project.group}.protocol,${project.group},org.slf4j,javax.servlet,javax.servlet.http\";version=\"${project.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=\"${project.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=\"${project.version}\",${project.group}.meta_data;uses:=\"${project.group}\";version=\"${project.version}\",${project.group}.scheme;uses:=\"${project.group}.protocol,${project.group}\";version=\"${project.version}\",${project.group}.annotation;version=\"${project.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"
        ])
    }
}
