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

// ----------------------------------------------------------------------------
// Installation subtasks, not used currently, we use "make install/fast"
task installDist(type: Copy, group: 'Install') {
    description = "Copy Thrift JAR and dependencies into $installPath location"

    destinationDir = file(installPath)

    from jar
    from configurations.compile
}

task installJavadoc(type: Copy, group: 'Install', dependsOn: javadoc) {
    description = "Install Thrift JavaDoc into $installJavadocPath location"

    destinationDir = file(installJavadocPath)

    from javadoc.destinationDir
}

// This is not needed by Gradle builds but the remaining Ant builds seem to
// need access to the generated test classes for Thrift unit tests so we
// assist them to use it this way.
task copyDependencies(type: Copy, group: 'Build') {
    description = 'Copy runtime dependencies in a common location for other Ant based projects'
    project.assemble.dependsOn it

    destinationDir = file("$buildDir/deps")
    from configurations.testRuntime
    // exclude some very specific unit test dependencies
    exclude '**/junit*.jar', '**/mockito*.jar', '**/hamcrest*.jar'
}

// ----------------------------------------------------------------------------
// Allow this configuration to be shared between install and uploadArchives tasks
def configurePom(pom) {
    pom.project {
        name 'Apache Thrift'
        description 'Thrift is a software framework for scalable cross-language services development.'
        packaging 'jar'
        url 'http://thrift.apache.org'

        scm {
            url 'https://git-wip-us.apache.org/repos/asf?p=thrift.git'
            connection 'scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git'
            developerConnection 'scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git'
        }

        licenses {
            license {
                name 'The Apache Software License, Version 2.0'
                url "${project.license}"
                distribution 'repo'
            }
        }

        developers {
            developer {
                id 'dev'
                name 'Apache Thrift Developers'
                email 'dev@thrift.apache.org'
            }
        }
    }

    pom.whenConfigured {
        // Fixup the scope for servlet-api to be 'provided' instead of 'compile'
        dependencies.find { dep -> dep.groupId == 'javax.servlet' && dep.artifactId == 'servlet-api' }.with {
            // it.optional = true
            it.scope = 'provided'
        }
    }
}

install {
    repositories.mavenInstaller {
        configurePom(pom)
    }
}

uploadArchives {
    dependsOn test // make sure we run unit tests when publishing
    repositories.mavenDeployer {
        // signPom will silently do nothing when no signing information is provided
        beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
        repository(url: project.mavenRepositoryUrl) {
            if (project.hasProperty('mavenUser') && project.hasProperty('mavenPassword')) {
                authentication(userName: mavenUser, password: mavenPassword)
            }
        }
        configurePom(pom)
    }
}

// Signing configuration, optional, only when release and uploadArchives is activated
signing {
    required { !version.endsWith("SNAPSHOT") && gradle.taskGraph.hasTask("uploadArchives") }
    sign configurations.archives
}
