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


// For Solr, a 'resolve' task is much more complex. There are three folders:
// lib/
// test-lib/
//
// There doesn't seem to be one ideal set of rules on how these should be created, but
// I tried to imitate the current (master) logic present in ivy and ant files in this way:
//
// The "solr platform" set of dependencies is a union of all deps for (core, solrj, server).
//
// Then:
// lib - these are module's "own" dependencies.
// test-lib/ - libs not present in solr platform.
//
// None of these are really needed with gradle... they should be collected just in the distribution
// package, not at each project's level.
//
// Unfortunately this "resolution" process is also related to how the final Solr packaging is assembled.
// I don't know how to untie these two cleanly.
//

configure(allprojects.findAll {project -> project.path.startsWith(":solr:modules:") || project.path == ":solr:prometheus-exporter" || project.path == ":solr:cross-dc-manager" }) {
  plugins.withType(JavaPlugin) {
    project.ext {
      packagingDir = file("${buildDir}/packaging")
      if (project.path.startsWith(":solr:prometheus-exporter") || project.path.startsWith(":solr:cross-dc-manager")) {
        deps = packagingDir
      } else {
        deps = file("${packagingDir}/${project.name}")
      }
    }

    configurations {
      solrPlatformLibs
      runtimeLibs {
        extendsFrom runtimeElements
      }
      packaging
    }

    dependencies {
      solrPlatformLibs project(":solr:core")
      solrPlatformLibs project(":solr:solrj")
      solrPlatformLibs project(":solr:api")
      solrPlatformLibs project(":solr:solrj-zookeeper")
      // libExt has logging libs, which we don't want.  Lets users decide what they want.
      solrPlatformLibs project(path: ":solr:server", configuration: 'libExt')

      // The cross-dc-manager uses the cross-dc Solr module libraries as well as the Jetty server jars
      if (project.path == ":solr:cross-dc-manager") {
        solrPlatformLibs project(":solr:modules:cross-dc")
        solrPlatformLibs project(path: ":solr:server", configuration: 'serverLib')
      }
    }

    // An aggregate that configures lib and test-lib in a temporary location.
    task assemblePackaging(type: Sync) {
      from "README.md"

      from (tasks.jar, {
        into "lib"
      })

      from ({
        def externalLibs = configurations.runtimeLibs.copyRecursive { dep ->
          if (dep instanceof org.gradle.api.artifacts.ProjectDependency) {
            return !dep.dependencyProject.path.startsWith(":solr")
          } else {
            return true
          }
        }
        return externalLibs - configurations.solrPlatformLibs
      }, {
        into "lib"
      })

      into deps
    }

    task syncLib(type: Sync) {
      dependsOn assemblePackaging

      from(file("${deps}/lib"), {
        include "**"
      })
      into file("${projectDir}/lib")
    }

    task syncTestLib(type: Sync) {
      // From test runtime classpath exclude:
      // 1) project dependencies (and their dependencies)
      // 2) runtime dependencies
      // What remains is this module's "own" test dependency.
      from({
        def testRuntimeLibs = configurations.testRuntimeClasspath.copyRecursive { dep ->
          !(dep instanceof org.gradle.api.artifacts.ProjectDependency)
        }

        return testRuntimeLibs - configurations.runtimeLibs
      })

      into file("${projectDir}/test-lib")
    }

    // Module packaging currently depends on internal resolve.
    artifacts {
      packaging packagingDir, {
        builtBy assemblePackaging
      }
    }
  }
}

configure(project(":solr:example")) {
  evaluationDependsOn(":solr:example") // explicitly wait for other configs to be applied
}

configure(project(":solr:server")) {
  evaluationDependsOn(":solr:server")
}

configure(project(":solr:core")) {
  evaluationDependsOn(":solr:core")

  configurations {
    runtimeLibs {
      extendsFrom runtimeElements
    }
  }
}

configure(project(":solr:solrj")) {
  evaluationDependsOn(":solr:solrj")
}
