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

import java.nio.file.Paths

def expectedPomFile = Paths.get(projectDir.toString(), 'src', 'test', 'resources', 'expected-pom.xml')

task('checkPom') {
  // The XmlParser used below has a strange tendency to return lists of fields rather than the field
  // you actually want. Be careful with that, future developer.
  group 'verification'
  dependsOn('generatePomFileForMavenPublication')
  description 'Checks the generated POM against an expected POM for dependency changes.' +
    '  Ignores versions of Apache Geode dependencies.'

  def actualPomFile = tasks.named('generatePomFileForMavenPublication').get().outputs.files.first()
  def thisOutput = project.buildDir.toPath().resolve('reports').resolve('checkPom.out')
  inputs.files { [expectedPomFile, actualPomFile] }
  outputs.files { thisOutput }

  // We impose the following rules on our produced poms:
  // * Versions are to be specified in the <dependencyManagement> block, not the <dependency> block
  // * org.apache.geode versions will be ignored, in favor of this build's version
  // * <dependency> blocks in produced POMs are as expected (ordering ignored)
  // * <dependencyManagement> blocks in produced POMs are as expected (ordering ignored)
  // * Published groupId = "org.apache.geode"
  // * Published artifactId = project.artifactName if it exists, else project.name

  def anyVersionDefinitionNotInDependencyManagement = { pom ->
    pom.dependencies.dependency.any {
      it.get("version")*.value() != []
    }
  }

  def ignoreGeodeVersionInExpectedPom = { pom ->
    pom.dependencyManagement.dependencies.dependency.each { dep ->
      if (dep.toString().contains("org.apache.geode")) {
        // since the project version is the source of truth, use that for comparison instead of
        // whatever is stored in the expected pom file
        dep.get("version")*.setValue([version])
      }
    }
  }

  def dependenciesBlocksMatch = { actual, expected ->
    def actualTreeSet = actual.dependencies.dependency.collect {it.toString()}.toSet()
    def expectedTreeSet = expected.dependencies.dependency.collect {it.toString()}.toSet()
    actualTreeSet.equals(expectedTreeSet)
  }

  def groupMismatches = { pom ->
    def groupId = pom["groupId"]
    groupId*.value().flatten().any {
      it != project.group
    }
  }

  def artifactMismatches = { pom ->
    // This work-around for 'artifactName' or 'project.name' is for geode-assembly, which re-names its output
    def artifactId = pom["artifactId"]
    artifactId*.value().flatten().any {
      it != (project.findProperty('artifactName') ?: project.name)
    }
  }

  doLast {
    if (tasks.getByName("generatePomFileForMavenPublication").enabled) {
      if (null == expectedPomFile) {
        throw new RuntimeException("expected-pom.xml not found.")
      }
      def expectedPom = new XmlParser().parse(expectedPomFile.toString())
      ignoreGeodeVersionInExpectedPom(expectedPom)

      // Sanity checks against the expected pom.
      def pathologicalArtifactId = artifactMismatches(expectedPom)
      def pathologicalGroupId = groupMismatches(expectedPom)
      def pathologicalVersionedDeps = anyVersionDefinitionNotInDependencyManagement(expectedPom)

      if (pathologicalArtifactId || pathologicalGroupId || pathologicalVersionedDeps) {
        def errorSummary = ""
        errorSummary += pathologicalArtifactId ? "Expected POM header pathologically incorrect. Fix artifactId to match subproject name.\n" : ""
        errorSummary += pathologicalGroupId ? "Expected POM header pathologically incorrect. Fix groupId to be 'org.apache.geode'.\n" : ""
        errorSummary += pathologicalVersionedDeps ? "Expected POM should not declare dependency versions outside the Spring dependency-management constraints." : ""
        throw new GradleException(errorSummary)
      }

      def actualPom = new XmlParser().parse(actualPomFile)

      def badArtifactId = artifactMismatches(actualPom)
      def badGroupId = groupMismatches(actualPom)
      def improperlyVersionedDeps = anyVersionDefinitionNotInDependencyManagement(actualPom)
      def depsMismatch = !dependenciesBlocksMatch(expectedPom, actualPom)
      def versionMismatch = !dependenciesBlocksMatch(expectedPom.dependencyManagement, actualPom.dependencyManagement)

      if (badArtifactId || badGroupId || improperlyVersionedDeps || depsMismatch || versionMismatch) {
        def errorSummary = ""
        errorSummary += badArtifactId ? "POM header information incorrect. Fix artifactId.\n" : ""
        errorSummary += badGroupId ? "POM header information incorrect. Fix groupId.\n" : ""
        errorSummary += improperlyVersionedDeps ? "Version definition should be in the <dependencyManagement> block only.\n" : ""
        errorSummary += depsMismatch ? "<dependencies> blocks do not match.\n" : ""
        errorSummary += versionMismatch ? "<dependencyManagement> blocks do not match.\n" : ""

        def message = """
The POM produced by the ${project.name}'s publication task has changed from expectation.
This is typically the result of changing or new dependencies, or dependency versions.
The actual publication candidate POM can be found here: ${actualPomFile}
The associated expected POM can be found here: ${expectedPomFile}

${errorSummary}
Please review the differences between the files indicated above.
This task is meant to be comprehensive -- there should be no change in the POM for which you are not responsible.
A possible exception is the listed Geode project dependencies, which are modified to reflect the current build's version.

Once the differences in the above files are reviewed and confirmed to be intentional,
  please update the expected POM file to reflect your changes.
Alternatively, run './gradlew ${project.path}:updateExpectedPom' to replace the expected POM with the generated POM.
"""
        thisOutput.write(message)
        throw new RuntimeException(message)
      }
    }
  }
}
check.dependsOn('checkPom')

task updateExpectedPom(dependsOn: generatePomFileForMavenPublication, type: Copy) {
  description 'After having verified changes with checkPom, this task will perform the copy.'

  def expectedPomDir = expectedPomFile.parent
  def actualPomFile = generatePomFileForMavenPublication.outputs.files.first()
  if (tasks.getByName("generatePomFileForMavenPublication").enabled) {
    from actualPomFile
    into expectedPomDir
    rename '.*.xml', "expected-pom.xml"
  }
}
checkPom.mustRunAfter(updateExpectedPom)
