/*
 * 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 "2.0.0"
  id "org.owasp.dependencycheck" version "5.3.0"
  id 'de.thetaphi.forbiddenapis' version '3.2' apply false
  id "de.undercouch.download" version "4.1.1" apply false
  id "net.ltgt.errorprone" version "2.0.2" apply false
  id 'com.diffplug.spotless' version "5.14.3" apply false
}

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

// General metadata.

// Calculate project version:
version = {
  // Release manager: update base version here after release:
  String baseVersion = '9.1.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'

// 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 new 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 new GradleException("Can't strip version to just major version: " + rootProject.version)
    }
    return m[0][1] as int
  }

  // Minimum Java version required to compile and run Lucene.
  minJavaVersion = JavaVersion.VERSION_11

  // 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)

  // 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
  }
}

configurations {
  groovy
}

dependencies {
  // Use a newer groovy that doesn't have illegal reflective accesses.
  groovy "org.codehaus.groovy:groovy-all:3.0.9"
}

apply from: file('buildSrc/scriptDepVersions.gradle')

// 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/generation/local-settings.gradle')

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

// Set up defaults and configure aspects for certain modules or functionality
// (java, tests)
apply from: file('gradle/java/folder-layout.gradle')
apply from: file('gradle/java/javac.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/java/jar-manifest.gradle')
apply from: file('gradle/java/modules.gradle')

// Maven artifact publishing.
apply from: file('gradle/maven/publications.gradle')

// Validation tasks
apply from: file('gradle/validation/measure-task-times.gradle')
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/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/spotless.gradle')

// Source or data regeneration tasks
apply from: file('gradle/generation/regenerate.gradle')
apply from: file('gradle/generation/jflex.gradle')
apply from: file('gradle/generation/moman.gradle')
apply from: file('gradle/generation/snowball.gradle')
apply from: file('gradle/generation/kuromoji.gradle')
apply from: file('gradle/generation/nori.gradle')
apply from: file('gradle/generation/icu.gradle')
apply from: file('gradle/generation/javacc.gradle')
apply from: file('gradle/generation/forUtil.gradle')
apply from: file('gradle/generation/antlr.gradle')

apply from: file('gradle/datasets/external-datasets.gradle')

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

// Additional development aids.
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/testing/coverage.gradle')
apply from: file('gradle/help.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/documentation/check-broken-links.gradle')

apply from: file('gradle/hacks/gradle-archives.gradle')
apply from: file('gradle/hacks/wipe-temp.gradle')
apply from: file('gradle/hacks/hashmapAssertions.gradle')
apply from: file('gradle/hacks/turbocharge-jvm-opts.gradle')
apply from: file('gradle/hacks/dummy-outputs.gradle')

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