/*
 * 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://github.com/apache/thrift'
            connection 'scm:git:https://github.com/apache/thrift.git'
            developerConnection 'scm:git:git@github.com:apache/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 == 'javax.servlet-api' }.with {
            if(it != null) {
              // 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
}
