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

//
// Configure test randomization seeds and derived test properties.
//

import java.nio.file.*
import com.carrotsearch.randomizedtesting.SeedUtils
import com.carrotsearch.randomizedtesting.generators.RandomPicks
import org.apache.tools.ant.types.Commandline

buildscript {
  repositories {
    mavenCentral()
  }

  dependencies {
    classpath 'com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.7.9'
  }
}

class SecurityArgumentProvider implements CommandLineArgumentProvider {
  @Internal
  Directory commonSolrDir

  @InputFile
  @PathSensitive(PathSensitivity.RELATIVE)
  RegularFile javaSecurityPolicy

  @Override
  Iterable<String> asArguments() {
    [
        "-Dcommon-solr.dir=${commonSolrDir.getAsFile()}",
        "-Djava.security.policy=${javaSecurityPolicy.getAsFile()}"
    ]
  }
}

def resources = scriptResources(buildscript)

// Pick the "root" seed from which everything else is derived.
configure(rootProject) {
  ext {
    rootSeed = propertyOrDefault('tests.seed', String.format("%08X", new Random().nextLong()))
    rootSeedUserProvided = (propertyOrDefault('tests.seed', null) != null)
    rootSeedLong = SeedUtils.parseSeedChain(rootSeed)[0]
    projectSeedLong = rootSeedLong ^ project.path.hashCode()
  }

  task randomizationInfo() {
    doFirst {
      logger.lifecycle("Running tests with randomization seed: tests.seed=${rootSeed}")
    }
  }
}

// Any test task will trigger display of randomization settings.
allprojects {
  tasks.withType(Test) { task ->
    task.dependsOn rootProject.randomizationInfo
  }
}

// Configure test property defaults and their descriptions.
allprojects {
  plugins.withType(JavaPlugin) {
    ext {
      testOptions += [
          // seed, repetition and amplification.
          [propName: 'tests.seed', value: { -> rootSeed }, description: "Sets the master randomization seed."],
          [propName: 'tests.iters', value: null, description: "Duplicate (re-run) each test case N times."],
          [propName: 'tests.multiplier', value: 1, description: "Value multiplier for randomized tests."],
          [propName: 'tests.maxfailures', value: null, description: "Skip tests after a given number of failures."],
          [propName: 'tests.timeoutSuite', value: null, description: "Timeout (in millis) for an entire suite."],
          [propName: 'tests.failfast', value: "false", description: "Stop the build early on failure.", buildOnly: true],
          // asserts, debug output.
          [propName: 'tests.asserts', value: "true", description: "Enables or disables assertions mode."],
          [propName: 'tests.infostream', value: false, description: "Enables or disables infostream logs."],
          [propName: 'tests.leaveTemporary', value: false, description: "Leave temporary directories after tests complete."],
          [propName: 'tests.useSecurityManager', value: true, description: "Control security manager in tests.", buildOnly: true],
          // component randomization
          [propName: 'tests.codec', value: "random", description: "Sets the codec tests should run with."],
          [propName: 'tests.directory', value: "random", description: "Sets the Directory implementation tests should run with."],
          [propName: 'tests.postingsformat', value: "random", description: "Sets the postings format tests should run with."],
          [propName: 'tests.docvaluesformat', value: "random", description: "Sets the doc values format tests should run with."],
          [propName: 'tests.locale', value: "random", description: "Sets the default locale tests should run with."],
          [propName: 'tests.timezone', value: "random", description: "Sets the default time zone tests should run with."],
          // filtering
          [propName: 'tests.filter', value: null, description: "Applies a test filter (see :helpTests)."],
          [propName: 'tests.nightly', value: false, description: "Enables or disables @Nightly tests."],
          [propName: 'tests.weekly', value: false, description: "Enables or disables @Weekly tests."],
          [propName: 'tests.monster', value: false, description: "Enables or disables @Monster tests."],
          [propName: 'tests.awaitsfix', value: null, description: "Enables or disables @AwaitsFix tests."],
          [propName: 'tests.badapples', value: null, description: "Enables or disables @BadApple tests."],
          [propName: 'tests.file.encoding',
           value: { ->
             RandomPicks.randomFrom(new Random(projectSeedLong), ["US-ASCII", "ISO-8859-1", "UTF-8"])
           },
           description: "Sets the default file.encoding on test JVM.", buildOnly: true],
          // test data
          [propName: 'tests.linedocsfile', value: 'europarl.lines.txt.gz', description: "Test data file path."],
          // miscellaneous; some of them very weird.
          [propName: 'tests.bwcdir', value: null, description: "Data for backward-compatibility indexes."],
      ]
    }
  }
}

// Add Solr-specific test configs settings.
configure(allprojects.findAll {project -> project.path.startsWith(":solr") }) {
  plugins.withType(JavaPlugin) {
    ext {
      testOptions += [
          [propName: 'solr.directoryFactory', value: "org.apache.solr.core.MockDirectoryFactory", description: "Solr directory factory."],
          [propName: 'tests.src.home', value: null, description: "See SOLR-14023."],
          [propName: 'solr.tests.use.numeric.points', value: null, description: "Point implementation to use (true=numerics, false=trie)."],
      ]
    }
  }
}

// Resolve test option values after all evaluation is complete.
allprojects {
  plugins.withType(JavaPlugin) {
    afterEvaluate {
      ext.testOptionsResolved = testOptions.findAll { opt ->
        propertyOrDefault(opt.propName, opt.value) != null
      }.collectEntries { opt ->
        [(opt.propName): Objects.toString(resolvedTestOption(opt.propName))]
      }

      // Compute the "reproduce with" string.
      ext.testOptionsForReproduceLine = testOptions.findAll { opt ->
        if (opt["includeInReproLine"] == false) {
          return false
        }

        def defValue = Objects.toString(opt.value, null)
        def value = testOptionsResolved[opt.propName]
        return defValue != value
      }.collect { opt ->
        Commandline.quoteArgument("-P" + opt.propName + "=" + testOptionsResolved[opt.propName])
      }.join(" ")

      // leaving temporary folder option has multiple aliases...
      if ([
         "tests.leaveTemporary",
         "tests.leavetemporary",
         "tests.leavetmpdir",
         "solr.test.leavetmpdir",
      ].find { prop ->
        def v = Boolean.parseBoolean(propertyOrDefault(prop, "false"))
        if (v) {
          logger.lifecycle("Update your code to use the official 'tests.leaveTemporary' option (you used '${prop}').")
        }
        return v
      }) {
        testOptionsResolved['tests.leaveTemporary'] = "true"
      }

      // Append resolved test properties to the test task.
      tasks.withType(Test) { task ->
        // TODO: we could remove some options that are only relevant to the build environment
        // and not the test JVM itself.
        systemProperties testOptionsResolved

        if (Boolean.parseBoolean(testOptionsResolved['tests.asserts'])) {
          jvmArgs("-ea", "-esa")
        } else {
          enableAssertions = false
        }

        if (Boolean.parseBoolean(testOptionsResolved["tests.failfast"])) {
          failFast true
        }

        // The Lucene version is only available after resolving was done, so add lately using a provider:
        jvmArgumentProviders.add({
          def luceneMatchVersion = rootProject.luceneBaseVersionProvider.get()
          return [
            "-Dtests.LUCENE_VERSION=${luceneMatchVersion}",
            "-Dtests.luceneMatchVersion=${luceneMatchVersion}",
          ]
        } as CommandLineArgumentProvider)

        // Enable security manager, if requested. We could move the selection of security manager and security policy
        // to each project's build/ configuration but it seems compact enough to keep it here for now.
        if (Boolean.parseBoolean(testOptionsResolved["tests.useSecurityManager"])) {
          def commonSolrDir = project(':solr').layout.projectDirectory
          def javaSecurityPolicy = layout.projectDirectory.file("${resources}/policies/solr-tests.policy")
          jvmArgumentProviders.add(
              new SecurityArgumentProvider(
                  commonSolrDir: commonSolrDir,
                  javaSecurityPolicy: javaSecurityPolicy
              )
          )
          systemProperty 'java.security.manager', "org.apache.lucene.tests.util.TestSecurityManager"

          def gradleUserHome = project.gradle.getGradleUserHomeDir()
          systemProperty 'gradle.lib.dir', Paths.get(project.class.location.toURI()).parent.toAbsolutePath().toString().replace('\\', '/')
          systemProperty 'gradle.worker.jar', Paths.get("${gradleUserHome}/caches/${gradle.gradleVersion}/workerMain/gradle-worker.jar").toAbsolutePath().toString()
          systemProperty 'gradle.user.home', gradleUserHome.toPath().toAbsolutePath().toString()
        }

        doFirst {
          logger.debug("Will use test opts:\n" + testOptionsResolved.collect {k,v -> "${k}: ${v}"}.sort().join("\n"))
        }
      }
    }
  }
}

// Add a helper task to display resolved test property values with their defaults
// and descriptions.
allprojects {
  plugins.withType(JavaPlugin) {
    task testOpts() {
      group = 'Help (developer guides and hints)'
      description = "Display values of randomization settings for a given seed"

      doFirst {
        println "Test options for project ${project.path} and seed \"${rootSeed}\":"

        testOptions.sort { a, b -> a.propName.compareTo(b.propName) }.each { opt ->
          def defValue
          def computedValue = false
          if (opt.value instanceof Closure) {
            defValue = Objects.toString(opt.value(), null)
            computedValue = true
          } else {
            defValue = Objects.toString(opt.value, null)
          }

          def value = testOptionsResolved[opt.propName]
          println String.format(Locale.ROOT,
              "%s%-24s = %-8s # %s",
              (defValue != value ? "! " : computedValue ? "C " : "  "),
              opt.propName,
              value,
              (computedValue ? "(!= default: computed) " : (defValue != value ? "(!= default: ${defValue}) " : "")) + opt.description)
        }
      }
    }
  }
}
