/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

import org.apache.tools.ant.filters.ReplaceTokens
import org.elasticsearch.gradle.Version
import java.nio.file.Paths
import org.elasticsearch.gradle.internal.AbstractDependenciesTask

apply plugin: 'elasticsearch.internal-es-plugin'
apply plugin: 'elasticsearch.publish'
apply plugin: 'elasticsearch.internal-cluster-test'
apply plugin: 'elasticsearch.internal-yaml-rest-test'
apply plugin: 'elasticsearch.internal-java-rest-test'
apply plugin: 'elasticsearch.yaml-rest-compat-test'
apply plugin: 'elasticsearch.internal-test-artifact'

base {
  archivesName = 'x-pack-core'
}

esplugin {
  name = 'x-pack-core'
  description = 'Elasticsearch Expanded Pack Plugin - Core'
  classname ='org.elasticsearch.xpack.core.XPackPlugin'
  hasNativeController =false
  requiresKeystore =false
}

tasks.withType(AbstractDependenciesTask).configureEach {
  mapping from: /http.*/, to: 'httpclient' // pulled in by rest client
  mapping from: /commons-.*/, to: 'commons' // pulled in by rest client
  mapping from: /slf4j-.*/, to: 'slf4j'
}

configurations {
  signedCerts
  rootCert
}

dependencies {
  compileOnly project(":server")
  api project(':libs:grok')
  api project(":libs:ssl-config")

  api "org.apache.httpcomponents:httpclient:${versions.httpclient}"
  api "org.apache.httpcomponents:httpcore:${versions.httpcore}"
  api "org.apache.httpcomponents:httpcore-nio:${versions.httpcore}"
  api "org.apache.httpcomponents:httpasyncclient:${versions.httpasyncclient}"

  api "org.apache.httpcomponents.client5:httpclient5:${versions.httpclient5}"
  api "org.apache.httpcomponents.core5:httpcore5:${versions.httpcore5}"
  api "org.apache.httpcomponents.core5:httpcore5-h2:${versions.httpcore5}"

  // Ideally this would be `runtimeOnly` so that we don't accidentally write code against the SLF4j API
  // However, some child plugins (like security) need to use slf4j directly in order to manage logging for their dependencies :(
  // And due to the way our plugin loading handles java modules between dependent plugins, this plugin (x-pack-core) needs to declare
  //  a module dependency on slf4j (`requires org.slf4j`) so that security can also be dependent on it
  // And having a module dependency counts as using the jar, so we can't make it `runtimeOnly` :(

  implementation "org.slf4j:slf4j-api:${versions.slf4j}"
  runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:${versions.log4j}"

  api "commons-logging:commons-logging:${versions.commonslogging}"
  api "org.apache.logging.log4j:log4j-1.2-api:${versions.log4j}"

  api "commons-codec:commons-codec:${versions.commonscodec}"

  testImplementation project(path: ':modules:aggregations')
  testImplementation project(path: ':modules:data-streams')
  testImplementation project(':modules:mapper-extras')

  // security deps
  api 'com.unboundid:unboundid-ldapsdk:6.0.3'

  implementation project(":x-pack:plugin:core:template-resources")

  testImplementation "org.elasticsearch:mocksocket:${versions.mocksocket}"
  testImplementation project(path: ':modules:reindex')
  testImplementation project(path: ':modules:parent-join')
  testImplementation project(path: ':modules:lang-mustache')
  testImplementation project(path: ':modules:analysis-common')
  testImplementation project(path: ':modules:rest-root')
  testImplementation project(path: ':modules:health-shards-availability')
  // Needed for Fips140ProviderVerificationTests
  testCompileOnly('org.bouncycastle:bc-fips:1.0.2.6')

  testImplementation(project(':x-pack:license-tools')) {
    transitive = false
  }

  yamlRestTestImplementation project(':x-pack:plugin:core')
  javaRestTestImplementation(testArtifact(project(xpackModule('core'))))
  signedCerts fileTree("src/test/resources/org/elasticsearch/xpack/security/transport/ssl/certs/simple/nodes/ca-signed")
  rootCert files("src/test/resources/org/elasticsearch/xpack/security/transport/ssl/certs/simple/nodes/ca.crt")
}

ext.expansions = [
  'project.version': version
]

tasks.named("processResources").configure {
  from(sourceSets.main.resources.srcDirs) {
    // we need to have duplicate strategy here as
    // we cannot apply the filter on root level due
    // to wrong behaviour with binary files.
    duplicatesStrategy = DuplicatesStrategy.INCLUDE
    exclude '**/public.key'
    inputs.properties(expansions)
    filter("tokens": expansions, ReplaceTokens.class)
  }
  String licenseKey = providers.systemProperty("license.key").getOrNull()
  if (licenseKey != null) {
    println "Using provided license key from ${licenseKey}"
  } else if (buildParams.snapshotBuild) {
    licenseKey = Paths.get(project.projectDir.path, 'snapshot.key')
  } else {
    throw new IllegalArgumentException('Property license.key must be set for release build')
  }
  File licenseKeyFile = layout.settingsDirectory.file(licenseKey).asFile
  if (licenseKeyFile.exists() == false) {
    throw new IllegalArgumentException('license.key at specified path [' + licenseKey + '] does not exist')
  }
  from(licenseKeyFile) {
    rename { String filename -> 'public.key' }
  }
}

tasks.named("forbiddenPatterns").configure {
  exclude '**/*.key'
  exclude '**/*.p12'
  exclude '**/*.der'
  exclude '**/*.zip'
}

tasks.named('forbiddenApisMain').configure {
  signaturesFiles += files('forbidden/hasher-signatures.txt')
}


// make LicenseSigner available for testing signed licenses
sourceSets.test.resources {
  srcDir 'src/main/config'
}

tasks.named("thirdPartyAudit").configure {
  ignoreMissingClasses(
    //commons-logging optional dependencies
    'org.apache.avalon.framework.logger.Logger',
    'org.apache.log.Hierarchy',
    'org.apache.log.Logger',
    //commons-logging provided dependencies
    'javax.servlet.ServletContextEvent',
    'javax.servlet.ServletContextListener',
    'javax.jms.Message',
    // HttpClient5 can use Conscrypt (TLS using BoringSSL), but we don't want that
    'org.conscrypt.Conscrypt',
    // SLF4j via HttpClient5
    'org.slf4j.ext.EventData'
  )
}

restResources {
  restApi {
    include '*'
  }
}

tasks.named("javaRestTest") {
  usesDefaultDistribution("uses the _xpack api")
}

if (buildParams.inFipsJvm) {
  // Test clusters run with security disabled
  tasks.named("javaRestTest").configure { enabled = false }
}

//this specific test requires a test only system property to be set, so we run it in a different JVM via a separate task
tasks.register('testAutomatonPatterns', Test) {
  include '**/AutomatonPatternsTests.class'
  systemProperty 'tests.automaton.record.patterns', 'true'
  testClassesDirs = sourceSets.test.output.classesDirs
  classpath = sourceSets.test.runtimeClasspath
}

tasks.named('test').configure {
  exclude '**/AutomatonPatternsTests.class'
}

tasks.named("check").configure { dependsOn "testAutomatonPatterns" }
