/*
 * 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.time.ZonedDateTime
import java.time.format.DateTimeFormatter

plugins {
  id "base"
  id "com.palantir.consistent-versions" version "1.14.0"
  id "org.owasp.dependencycheck" version "5.3.0"
  id 'de.thetaphi.forbiddenapis' version '3.1' apply false
  id "de.undercouch.download" version "4.0.2" apply false
  id "net.ltgt.errorprone" version "1.2.1" apply false
  id "com.palantir.docker" version "0.25.0" apply false
  id 'com.diffplug.spotless' version "5.8.2" apply false
}

apply from: file('gradle/defaults.gradle')

// General metadata.

// Calculate project version:
version = {
  // Release manager: update base version here after release:
  String baseVersion = '9.0.0'

  // On a release explicitly set release version in one go:
  //  -Dversion.release=x.y.z
  
  // Jenkins can just set just a suffix, overriding SNAPSHOT, e.g. using build id:
  //  -Dversion.suffix=jenkins123
  
  String versionSuffix = propertyOrDefault('version.suffix', 'SNAPSHOT')
  return propertyOrDefault('version.release', "${baseVersion}-${versionSuffix}")
}()
description = 'Grandparent project for Apache Lucene Core and Apache Solr'

// Propagate version and derived properties across projects.
allprojects {
  version = rootProject.version
}

ext {
  // "base" version is stripped of the qualifier. Compute it.
  baseVersion = {
    def m = (version =~ /^(\d+\.\d+\.\d+)(-(.+))?/)
    if (!m) {
      throw GradleException("Can't strip version to just x.y.z: " + rootProject.version)
    }
    return m[0][1]
  }()
  // "majorVersion" is an integer with just the major version. Compute it.
  majorVersion = {
    def m = (version =~ /^(\d+)\.\d+\.\d+(-(.+))?/)
    if (!m) {
      throw GradleException("Can't strip version to just major version: " + rootProject.version)
    }
    return m[0][1] as int
  }
  // snapshot build marker used in scripts.
  snapshotBuild = version.contains("SNAPSHOT")

  // Build timestamp.
  def tstamp = ZonedDateTime.now()
  buildDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(tstamp)
  buildTime = DateTimeFormatter.ofPattern("HH:mm:ss").format(tstamp)
  buildYear = DateTimeFormatter.ofPattern("yyyy").format(tstamp)

  minJavaVersion = JavaVersion.VERSION_11

  // Declare script dependency versions outside of palantir's
  // version unification control. These are not our main dependencies.
  scriptDepVersions = [
      "apache-rat": "0.11",
      "commons-codec": "1.13",
      "ecj": "3.19.0",
      "javacc": "7.0.4",
      "jflex": "1.7.0",
      "jgit": "5.9.0.202009080501-r",
      "flexmark": "0.61.24",
  ]

  // Allow definiting external tool locations using system props.
  externalTool = { name ->
    def resolved = propertyOrDefault("${name}.exe", name as String)
    logger.info("External tool '${name}' resolved to: ${resolved}")
    return resolved
  }
}

// Include smaller chunks configuring dedicated build areas.
// Some of these intersect or add additional functionality.
// The order of inclusion of these files shouldn't matter (but may
// if the build file is incorrectly written and evaluates something
// eagerly).

apply from: file('gradle/generate-defaults.gradle')

// Ant-compatibility layer: apply folder layout early so that
// evaluation of other scripts doesn't need to be deferred.
apply from: file('gradle/ant-compat/folder-layout.gradle')

// Set up defaults and configure aspects for certain modules or functionality
// (java, tests)
apply from: file('gradle/defaults-java.gradle')
apply from: file('gradle/testing/defaults-tests.gradle')
apply from: file('gradle/testing/randomization.gradle')
apply from: file('gradle/testing/fail-on-no-tests.gradle')
apply from: file('gradle/testing/alternative-jdk-support.gradle')
apply from: file('gradle/jar-manifest.gradle')

// Publishing and releasing
apply from: file('gradle/maven/defaults-maven.gradle')
apply from: file('gradle/releasing.gradle')

// IDE support, settings and specials.
apply from: file('gradle/ide/intellij-idea.gradle')
apply from: file('gradle/ide/eclipse.gradle')

// Validation tasks
apply from: file('gradle/validation/error-prone.gradle')
apply from: file('gradle/validation/precommit.gradle')
apply from: file('gradle/validation/forbidden-apis.gradle')
apply from: file('gradle/validation/jar-checks.gradle')
apply from: file('gradle/validation/git-status.gradle')
apply from: file('gradle/validation/versions-props-sorted.gradle')
apply from: file('gradle/validation/validate-source-patterns.gradle')
apply from: file('gradle/validation/config-file-sanity.gradle')
apply from: file('gradle/validation/rat-sources.gradle')
apply from: file('gradle/validation/owasp-dependency-check.gradle')
apply from: file('gradle/validation/ecj-lint.gradle')
apply from: file('gradle/validation/gradlew-scripts-tweaked.gradle')
apply from: file('gradle/validation/validate-log-calls.gradle')
apply from: file('gradle/validation/check-broken-links.gradle')
apply from: file('gradle/validation/spotless.gradle')

// Source or data regeneration tasks
apply from: file('gradle/generation/jflex.gradle')
apply from: file('gradle/generation/javacc.gradle')
apply from: file('gradle/generation/util.gradle')
apply from: file('gradle/generation/snowball.gradle')
apply from: file('gradle/generation/kuromoji.gradle')
apply from: file('gradle/generation/nori.gradle')

// Shared configuration of subprojects containing native code.
apply from: file('gradle/native/disable-native.gradle')

// Additional development aids.
apply from: file('gradle/maven/maven-local.gradle')
apply from: file('gradle/testing/per-project-summary.gradle')
apply from: file('gradle/testing/slowest-tests-at-end.gradle')
apply from: file('gradle/testing/failed-tests-at-end.gradle')
apply from: file('gradle/testing/profiling.gradle')
apply from: file('gradle/testing/beasting.gradle')
apply from: file('gradle/help.gradle')

// Ant-compatibility layer. ALL OF THESE SHOULD BE GONE at some point. They are
// here so that we can coexist with current ant build but they are indicative
// of potential problems with the build conventions, dependencies, etc.
apply from: file('gradle/ant-compat/force-versions.gradle')
apply from: file('gradle/ant-compat/misc.gradle')
apply from: file('gradle/ant-compat/post-jar.gradle')
apply from: file('gradle/ant-compat/test-classes-cross-deps.gradle')
apply from: file('gradle/ant-compat/artifact-naming.gradle')

apply from: file('gradle/documentation/documentation.gradle')
apply from: file('gradle/documentation/changes-to-html.gradle')
apply from: file('gradle/documentation/markdown.gradle')
apply from: file('gradle/documentation/render-javadoc.gradle')

apply from: file('gradle/hacks/gradle-archives.gradle')
apply from: file('gradle/hacks/findbugs.gradle')
apply from: file('gradle/hacks/gradle.gradle')
apply from: file('gradle/hacks/hashmapAssertions.gradle')

apply from: file('gradle/solr/packaging.gradle')
apply from: file('gradle/solr/solr-forbidden-apis.gradle')
