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

// This configures application of forbidden API rules
// via https://github.com/policeman-tools/forbidden-apis

def resources = scriptResources(buildscript)

// Only apply forbidden-apis to java projects.
allprojects { prj ->
  plugins.withId("java", {
    prj.apply plugin: 'de.thetaphi.forbiddenapis'

    // This helper method appends signature files based on a set of true
    // dependencies from a given configuration.
    def dynamicSignatures = { configuration, suffix ->
      def resolvedMods = configuration.resolvedConfiguration.resolvedArtifacts
          .collect { a -> a.moduleVersion.id }
      def deps = resolvedMods
          .collect { id -> [
              "${id.group}.${id.name}.all.txt",
              "${id.group}.${id.name}.${suffix}.txt",
          ]}
          .flatten()
          .sort()

      deps += ["defaults.all.txt", "defaults.${suffix}.txt"]

      deps.each { sig ->
        def signaturesFile = file("${resources}/${sig}")
        if (signaturesFile.exists()) {
          logger.info("Signature file applied: ${sig}")
          signaturesFiles += files(signaturesFile)
        } else {
          logger.debug("Signature file omitted (does not exist): ${sig}")
        }
      }
      
      // commons-io is special: forbiddenapis has a versioned bundledSignature.
      bundledSignatures += resolvedMods
        .findAll { id -> id.group == 'commons-io' && id.name == 'commons-io' }
        .collect { id -> "${id.name}-unsafe-${id.version}" as String }
    }

    // Configure defaults for sourceSets.main
    forbiddenApisMain {
      bundledSignatures += [
          'jdk-unsafe',
          'jdk-deprecated',
          'jdk-non-portable',
          'jdk-reflection',
          'jdk-system-out',
      ]

      suppressAnnotations += [
          "**.SuppressForbidden"
      ]
    }

    // Configure defaults for sourceSets.test
    forbiddenApisTest {
      bundledSignatures += [
          'jdk-unsafe',
          'jdk-deprecated',
          'jdk-non-portable',
          'jdk-reflection',
      ]

      signaturesFiles = files(
          file("${resources}/defaults.tests.txt")
      )

      suppressAnnotations += [
          "**.SuppressForbidden"
      ]
    }

    // Configure defaults for sourceSets.tools (if present).
    tasks.matching { it.name == "forbiddenApisTools" }.all {
      bundledSignatures += [
          'jdk-unsafe',
          'jdk-deprecated',
          'jdk-non-portable',
          'jdk-reflection',
      ]

      suppressAnnotations += [
          "**.SuppressForbidden"
      ]

      doFirst dynamicSignatures.curry(configurations.toolsCompileClasspath, "lucene")
      inputs.dir(file(resources))
    }

    // Disable sysout signatures for these projects.
    if (prj.path in [
        ":lucene:demo",
        ":lucene:benchmark",
        ":lucene:test-framework",
        ":solr:solr-ref-guide",
        ":solr:test-framework"
    ]) {
      forbiddenApisMain.bundledSignatures -= [
          'jdk-system-out'
      ]
    }

    // Configure lucene-specific rules.
    if (prj.path.startsWith(":lucene")) {
      forbiddenApisMain {
        doFirst dynamicSignatures.curry(configurations.compileClasspath, "lucene")
      }

      forbiddenApisTest {
        doFirst dynamicSignatures.curry(configurations.testCompileClasspath, "lucene")
      }
    }

    // Configure solr-specific rules.
    if (prj.path.startsWith(":solr")) {
      forbiddenApisMain {
        doFirst dynamicSignatures.curry(configurations.compileClasspath, "solr")
        signaturesFiles += files(file("${resources}/java.solr.txt"))
      }

      forbiddenApisTest {
        doFirst dynamicSignatures.curry(configurations.testCompileClasspath, "solr")
      }
    }

    // We rely on resolved configurations to compute the relevant set of rule
    // files for forbiddenApis. Since we don't want to resolve these configurations until
    // the task is executed, we can't really use them as task inputs properly. This is a
    // chicken-and-egg problem.
    //
    // This is the simplest workaround possible: just point at all the rule files and indicate
    // them as inputs. This way if a rule is modified, checks will be reapplied.
    configure([forbiddenApisMain, forbiddenApisTest]) { task ->
      task.inputs.dir(file(resources))
    }
  })
}