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


apply plugin: 'maven-publish'
apply plugin: 'signing'

// The published bom will constrain versions within geode of any subproject with this property set.
// This is normally set in publish.gradle, but since we do not consume that file, we opt in directly.
project.ext.set('constrainVersionInBom', true)

if (project.name != 'geode-assembly') {
  task sourcesJar(type: Jar) {
    from sourceSets.main.allJava
    classifier = 'sources'
  }

  task javadocJar(type: Jar) {
    from javadoc
    classifier = 'javadoc'
  }
}

def apacheLicense = '''
  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.
  '''

publishing {
  publications {
    maven(MavenPublication) {
      if (project.name != 'geode-assembly') {
        from components.java

        // use the (possibly empty) Jar tasks above for sources and javadoc
        artifact sourcesJar
        artifact javadocJar
      }

      pom {
        name = 'Apache Geode'
        description = 'Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing'
        url = 'http://geode.apache.org'

        scm {
          url = 'https://github.com/apache/geode'
          connection = 'scm:git:https://github.com:apache/geode.git'
          developerConnection = 'scm:git:https://github.com:apache/geode.git'
        }

        licenses {
          license {
            name = 'The Apache Software License, Version 2.0'
            url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
          }
        }

        withXml {
          // This black magic checks to see if a dependency has the flag ext.optional=true
          // set on it, and if so marks the dependency as optional in the maven pom
          def depMap = project.configurations.compile.dependencies.collectEntries { [it.name, it] }
          def runtimeDeps = project.configurations.runtime.dependencies.collectEntries {
            [it.name, it]
          }
          depMap.putAll(runtimeDeps)
          def runtimeOnlyDeps = project.configurations.runtimeOnly.dependencies.collectEntries {
            [it.name, it]
          }
          depMap.putAll(runtimeOnlyDeps)
          def implementationDependencies = project.configurations.implementation.dependencies.collectEntries {
            [it.name, it]
          }
          depMap.putAll(implementationDependencies)
          def apiDependencies = project.configurations.api.dependencies.collectEntries {
            [it.name, it]
          }
          depMap.putAll(apiDependencies)
          asNode().dependencies.dependency.findAll {
            def dep = depMap.get(it.artifactId.text())
            return dep?.hasProperty('optional') && dep.optional
          }.each {
            if (it.optional) {
              it.optional.value = 'true'
            } else {
              it.appendNode('optional', 'true')
            }
          }
        }

        withXml {
          // Geode dependency versions, as with all versions, are locked by the
          // Spring dependency-management plugin.  We remove version specification as injected by
          // project dependencies, e.g., compile project(':geode-core')
          asNode().dependencies.dependency.each { dep ->
            if (dep.toString().contains("org.apache.geode")) {
              dep.remove(dep["version"])
            }
          }
        }
        afterEvaluate {
          withXml {
            def providerAsElement = asElement()
            providerAsElement.insertBefore(
                providerAsElement.ownerDocument().createComment(apacheLicense),
                providerAsElement.firstChild)
          }
        }
      }
    }
  }
  repositories {
    maven {
      // Use specified mavenRepository if provided, else use release or snapshot defaults.
      url = project.findProperty("mavenRepository") ?:
          project.isReleaseVersion ? project.mavenReleaseUrl : project.mavenSnapshotUrl
      if (url.toString().startsWith("http") || url.toString().startsWith("sftp")) {
        // Username / password credentials are only supported for http, https, and sftp repos.
        // See the Gradle documentation on Repository Types for more information.
        credentials {
          username project.findProperty("mavenUsername")
          password project.findProperty("mavenPassword")
        }
      }
    }
  }
}

signing {
  required({project.isReleaseVersion && project.hasProperty('signing.keyId') && project.hasProperty('signing.secretKeyRingFile')})
  sign publishing.publications.maven
}

task install(dependsOn: publishToMavenLocal) {}

apply from: "${rootDir}/${scriptDir}/check-pom.gradle"
