/*
 * 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 adds validation of project dependencies:
// 1) license file
// 2) notice file
// 3) checksum validation/ generation.

import org.apache.commons.codec.digest.DigestUtils

// This should be false only for debugging.
def failOnError = true

// We're using commons-codec for computing checksums.
buildscript {
  repositories {
    mavenCentral()
  }

  dependencies {
    classpath "commons-codec:commons-codec:${scriptDepVersions['commons-codec']}"
  }
}

// Configure license checksum folder for top-level projects.
// (The file("licenses") inside the configure scope resolves
// relative to the current project so they're not the same).
if (!skipLucene) {
  configure(project(":lucene")) {
    ext.licensesDir = file("licenses")
  }
}

if (!skipSolr) {
  configure(project(":solr")) {
    ext.licensesDir = file("licenses")
  }
}

// All known license types. If 'noticeOptional' is true then
// the notice file must accompany the license.
def licenseTypes = [
    "ASL"     : [name: "Apache Software License 2.0"],
    "BSD"     : [name: "Berkeley Software Distribution"],
    //BSD like just means someone has taken the BSD license and put in their name, copyright, or it's a very similar license.
    "BSD_LIKE": [name: "BSD like license"],
    "CDDL"    : [name: "Common Development and Distribution License", noticeOptional: true],
    "CPL"     : [name: "Common Public License"],
    "EPL"     : [name: "Eclipse Public License Version 1.0", noticeOptional: true],
    "MIT"     : [name: "Massachusetts Institute of Tech. License", noticeOptional: true],
    "MPL"     : [name: "Mozilla Public License", noticeOptional: true /* NOT SURE on the required notice */],
    "PD"      : [name: "Public Domain", noticeOptional: true],
    "SUN"     : [name: "Sun Open Source License", noticeOptional: true],
    "COMPOUND": [name: "Compound license (details in NOTICE file)."],
]

allprojects {
  task licenses() {
    group = 'Dependency validation'
    description = "Apply all dependency/ license checks."
  }
  check.dependsOn(licenses)
}

subprojects {
  // Configure jarValidation configuration for all projects. Any dependency
  // declared on this configuration (or any configuration it extends from) will
  // be verified.
  configurations {
    jarValidation
  }

  // For Java projects, add all dependencies from the following configurations
  // to jar validation
  plugins.withType(JavaPlugin) {
    configurations {
      jarValidation {
        extendsFrom runtimeClasspath
        extendsFrom compileClasspath
        extendsFrom testRuntimeClasspath
        extendsFrom testCompileClasspath
      }
    }
  }

  // Collects dependency JAR information for a project and saves it in
  // project.ext.jarInfos. Each dependency has a map of attributes
  // which make it easier to process it later on (name, hash, origin module,
  // see the code below for details).
  task collectJarInfos() {
    dependsOn configurations.jarValidation

    doFirst {
      def isSolr = project.path.startsWith(":solr")

      // When gradle resolves a configuration it applies exclude rules from inherited configurations
      // globally (this seems like a bug to me). So we process each inherited configuration independently
      // but make sure there are no other dependencies on jarValidation itself.
      if (!configurations.jarValidation.dependencies.isEmpty()) {
        throw new GradleException("jarValidation must only inherit from other configurations (can't have its own dependencies).")
      }

      def excludeRules = configurations.jarValidation.excludeRules

      ArrayDeque<ResolvedDependency> queue = new ArrayDeque<>()
      configurations.jarValidation.extendsFrom.each { conf ->
        if (excludeRules) {
          conf = conf.copyRecursive()
          conf.canBeResolved = true
          conf.canBeConsumed = true
          conf.excludeRules = excludeRules
        }
        if (conf.canBeResolved) {
          queue.addAll(conf.resolvedConfiguration.firstLevelModuleDependencies)
        }
      }

      def visited = new HashSet<>()
      def infos = []

      while (!queue.isEmpty()) {
        def dep = queue.removeFirst()

        // Skip any artifacts from other Solr modules (they will be resolved there).
        if (dep.moduleGroup == "org.apache.solr") {
          continue
        }

        // Skip any artifacts from Lucene modules.
        if (dep.moduleGroup.startsWith("org.apache.lucene")) {
          // ... but process their transitive dependencies for Solr compatibility.
          if (isSolr) {
            queue.addAll(dep.children)
          }
        } else {
          queue.addAll(dep.children)
          dep.moduleArtifacts.each { resolvedArtifact ->
            def file = resolvedArtifact.file
            if (visited.add(file)) {
              infos.add([
                  name           : resolvedArtifact.name,
                  jarName        : file.toPath().getFileName().toString(),
                  path           : file,
                  module         : resolvedArtifact.moduleVersion,
                  checksum       : provider { new DigestUtils(DigestUtils.sha1Digest).digestAsHex(file).trim() },
                  // We keep track of the files referenced by this dependency (sha, license, notice, etc.)
                  // so that we can determine unused dangling files later on.
                  referencedFiles: []
              ])
            }
          }
        }
      }

      project.ext.jarInfos = infos.sort {a, b -> "${a.module}".compareTo("${b.module}")}
      // jarInfos.each { info -> println "${info.module}" }
    }
  }

  // Verifies that each JAR has a corresponding checksum and that it matches actual JAR available for this dependency.
  task validateJarChecksums() {
    group = 'Dependency validation'
    description = "Validate checksums of dependencies"
    dependsOn collectJarInfos

    doLast {
      def errors = []
      jarInfos.each { dep ->
        def expectedChecksumFile = file("${licensesDir}/${dep.jarName}.sha1")
        if (!expectedChecksumFile.exists()) {
          errors << "Dependency checksum missing ('${dep.module}'), expected it at: ${expectedChecksumFile}"
        } else {
          dep.referencedFiles += expectedChecksumFile
          def expected = expectedChecksumFile.getText("UTF-8").trim()
          def actual = dep.checksum.get()
          if (expected.compareToIgnoreCase(actual) != 0) {
            errors << "Dependency checksum mismatch ('${dep.module}'), expected it to be: ${expected}, but was: ${actual}"
          } else {
            logger.log(LogLevel.INFO, "Dependency checksum OK ('${dep.module}')")
          }
        }
      }

      if (errors) {
        def msg = "Dependency checksum validation failed:\n  - " + errors.join("\n  - ")
        if (failOnError) {
          throw new GradleException(msg)
        } else {
          logger.log(LogLevel.WARN, "WARNING: ${msg}")
        }
      }
    }
  }

  // Locate the set of license file candidates for this dependency. We
  // search for [jar-or-prefix]-LICENSE-[type].txt
  // where 'jar-or-prefix' can be any '-'-delimited prefix of the dependency JAR's name.
  // So for 'commons-io' it can be 'commons-io-LICENSE-foo.txt' or
  // 'commons-LICENSE.txt'
  task validateJarLicenses() {
    group = 'Dependency validation'
    description = "Validate license and notice files of dependencies"
    dependsOn collectJarInfos

    doLast {
      def errors = []
      jarInfos.each { dep ->
        def baseName = dep.name
        def found = []
        def candidates = []
        while (true) {
          candidates += file("${licensesDir}/${baseName}-LICENSE-[type].txt")
          found += fileTree(dir: licensesDir, include: "${baseName}-LICENSE-*.txt").files
          def prefix = baseName.replaceAll(/[\-][^-]+$/, "")
          if (found || prefix == baseName) {
            break
          }
          baseName = prefix
        }

        if (found.size() == 0) {
          errors << "License file missing ('${dep.module}'), expected it at: ${candidates.join(" or ")}," +
              " where [type] can be any of ${licenseTypes.keySet()}."
        } else if (found.size() > 1) {
          errors << "Multiple license files matching for ('${dep.module}'): ${found.join(", ")}"
        } else {
          def licenseFile = found.get(0)
          dep.referencedFiles += licenseFile
          def m = (licenseFile.name =~ /LICENSE-(.+)\.txt$/)
          if (!m) throw new GradleException("License file name doesn't contain license type?: ${licenseFile.name}")

          def licenseName = m[0][1]
          def licenseType = licenseTypes[licenseName]
          if (!licenseType) {
            errors << "Unknown license type suffix for ('${dep.module}'): ${licenseFile} (must be one of ${licenseTypes.keySet()})"
          } else {
            logger.log(LogLevel.INFO, "Dependency license file OK ('${dep.module}'): " + licenseName)

            // Look for sibling NOTICE file.
            def noticeFile = file(licenseFile.path.replaceAll(/\-LICENSE-.+/, "-NOTICE.txt"))
            if (noticeFile.exists()) {
              dep.referencedFiles += noticeFile
              logger.log(LogLevel.INFO, "Dependency notice file OK ('${dep.module}'): " + noticeFile)
            } else if (!licenseType.noticeOptional) {
              errors << "Notice file missing for ('${dep.module}'), expected it at: ${noticeFile}"
            }
          }
        }
      }

      if (errors) {
        def msg = "Certain license/ notice files are missing:\n  - " + errors.join("\n  - ")
        if (failOnError) {
          throw new GradleException(msg)
        } else {
          logger.log(LogLevel.WARN, "WARNING: ${msg}")
        }
      }
    }
  }

  licenses.dependsOn validateJarChecksums, validateJarLicenses
}

// Add top-project level tasks validating dangling files
// and regenerating dependency checksums.
def plist = []
if (!skipLucene) {
  plist.add(project(":lucene"))
}
if (!skipSolr) {
  plist.add(project(":solr"))
}

configure(plist) {
  def validationTasks = subprojects.collectMany { it.tasks.matching { it.name == "licenses" } }
  def jarInfoTasks = subprojects.collectMany { it.tasks.matching { it.name == "collectJarInfos" } }

  // Update dependency checksums.
  task updateLicenses() {
    group = 'Dependency validation'
    description = "Write or update checksums of dependencies. May need to run gradlew --write-locks first if changing dependency versions"
    dependsOn jarInfoTasks

    doLast {
      licensesDir.mkdirs()

      // Clean any previous checksums. In theory we wouldn't have to do it --
      // dangling files from any previous JARs would be reported;
      // it automates the process of updating versions and makes it easier though so
      // why not.
      project.delete fileTree(licensesDir, {
        include "*.sha1"
        exclude checkDanglingLicenseFiles.ext.exclude
      })

      def updated = []
      jarInfoTasks.collectMany { task -> task.project.jarInfos }.each { dep ->
        def expectedChecksumFile = file("${licensesDir}/${dep.jarName}.sha1")
        def actual = dep.checksum.get()
        if (expectedChecksumFile.exists()) {
          def expected = expectedChecksumFile.getText("UTF-8").trim()
          if (expected.compareToIgnoreCase(actual) == 0) {
            return;
          }
        }

        updated += "Updated checksum ('${dep.module}'): ${expectedChecksumFile}"
        expectedChecksumFile.write(actual + "\n", "UTF-8")
      }

      updated.sort().each { line -> logger.log(LogLevel.LIFECYCLE, line) }
    }
  }

  // Any validation task must run after all updates have been applied.
  // We add an ordering constraint that any validation task (or its dependency subgraph)
  // must run after updateLicenses
  validationTasks
      .collectMany { task -> [task, task.dependsOn]}
      .flatten()
      .each { task ->
        task.mustRunAfter updateLicenses
      }

  // Check for dangling files in the licenses folder.
  task checkDanglingLicenseFiles() {
    dependsOn validationTasks

    ext {
      exclude = []
    }

    doFirst {
      def allReferenced = validationTasks
          // Only collect for enabled tasks: https://issues.apache.org/jira/browse/LUCENE-9780
          .findAll { it.enabled }
          .collectMany { task ->
            task.project.jarInfos.collectMany { it.referencedFiles }
          }
          .collect { it.toString() }

      def patterns = ext.exclude
      def allExisting = fileTree(licensesDir, {
        exclude patterns
      }).files.collect { it.toString() }

      def dangling = (allExisting - allReferenced).sort()

      if (dangling) {
        gradle.buildFinished {
          logger.warn("WARNING: there were unreferenced files under license folder:\n  - ${dangling.join("\n  - ")}")
        }
      }
    }
  }

  licenses.dependsOn checkDanglingLicenseFiles
}

// Exclude files that are not a result of direct dependencies but have to be there.
// It would be probably better to move non-dependency licenses into the actual project
// where they're used and only assemble them for the distribution package.
if (!skipLucene) {
  configure(project(":lucene")) {
    checkDanglingLicenseFiles {
      exclude += [
          "elegant-icon-font-*",
          "ant-*",
          "ivy-*",
      ]
    }
  }
}

// SOLR ONLY
if (!skipSolr) {
  configure(project(":solr")) {
    checkDanglingLicenseFiles {
      exclude += [
          "README.committers.txt"
      ]
    }
  }

  // solr-ref-guide doesn't contribute any JARs to dependency checks.
  configure(project(":solr:solr-ref-guide")) {
    configurations {
      jarValidation {
        exclude group: "*"
      }
    }
  }
}