/*
 * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
 * Public License v 1"; you may not use this file except in compliance with, at
 * your election, the "Elastic License 2.0", the "GNU Affero General Public
 * License v3.0 only", or the "Server Side Public License, v 1".
 */


import org.elasticsearch.gradle.internal.test.InternalClusterTestPlugin
import org.elasticsearch.gradle.internal.test.RestIntegTestTask
import org.elasticsearch.gradle.internal.test.rest.LegacyJavaRestTestPlugin

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

/*
 TODOs:
   * fix permissions such that only netty4 can open sockets etc?
   * fix the hack in the build framework that copies transport-netty4 into the integ test cluster
 */
esplugin {
  description = 'Netty 4 based transport implementation'
  classname = 'org.elasticsearch.transport.netty4.Netty4Plugin'
}

// exclude transitively pulled in version via the esplugin plugin to always build from fresh sources and make jar-hell checks pass
configurations {
  [testCompileClasspath, testRuntimeClasspath, internalClusterTestCompileClasspath, internalClusterTestRuntimeClasspath].each {
    it.exclude group: 'org.elasticsearch.plugin', module: 'transport-netty4'
  }
}

dependencies {
  api project(":libs:ssl-config")

  // network stack
  api "io.netty:netty-buffer:${versions.netty}"
  api "io.netty:netty-codec:${versions.netty}"
  api "io.netty:netty-codec-http:${versions.netty}"
  api "io.netty:netty-common:${versions.netty}"
  api "io.netty:netty-handler:${versions.netty}"
  api "io.netty:netty-resolver:${versions.netty}"
  api "io.netty:netty-transport:${versions.netty}"
  api "io.netty:netty-transport-native-unix-common:${versions.netty}"

  testImplementation project(':modules:rest-root')

  clusterModules project(':modules:rest-root')
}

restResources {
  restApi {
    include '_common', 'cluster', 'nodes', 'ping'
  }
}

tasks.named("dependencyLicenses").configure {
  mapping from: /netty-.*/, to: 'netty'
}

TaskProvider<Test> pooledTest = tasks.register("pooledTest", Test) {
  include '**/*Tests.class'
  systemProperty 'es.use_unpooled_allocator', 'false'
  classpath = sourceSets.test.runtimeClasspath
  testClassesDirs = sourceSets.test.output.classesDirs
}

TaskProvider<Test> pooledInternalClusterTest = tasks.register("pooledInternalClusterTest", Test) {
  include '**/*IT.class'
  systemProperty 'es.use_unpooled_allocator', 'false'
  systemProperty 'es.insecure_network_trace_enabled', 'true'
  SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
  SourceSet internalTestSourceSet = sourceSets.getByName(InternalClusterTestPlugin.SOURCE_SET_NAME)
  setTestClassesDirs(internalTestSourceSet.getOutput().getClassesDirs())
  setClasspath(internalTestSourceSet.getRuntimeClasspath())
}

tasks.named("internalClusterTest").configure {
  systemProperty 'es.insecure_network_trace_enabled', 'true'
}

tasks.named("check").configure {
  dependsOn(pooledTest, pooledInternalClusterTest)
}

tasks.named("thirdPartyAudit").configure {
  ignoreMissingClasses(
    // classes are missing
    'com.aayushatharva.brotli4j.Brotli4jLoader',
    'com.aayushatharva.brotli4j.decoder.DecoderJNI$Status',
    'com.aayushatharva.brotli4j.decoder.DecoderJNI$Wrapper',
    'com.aayushatharva.brotli4j.encoder.BrotliEncoderChannel',
    'com.aayushatharva.brotli4j.encoder.Encoder$Mode',
    'com.aayushatharva.brotli4j.encoder.Encoder$Parameters',

    // from io.netty.handler.codec.protobuf.ProtobufDecoder (netty)
    'com.google.protobuf.ExtensionRegistry',
    'com.google.protobuf.MessageLite$Builder',
    'com.google.protobuf.MessageLite',
    'com.google.protobuf.Parser',

    // from io.netty.logging.CommonsLoggerFactory (netty)
    'org.apache.commons.logging.Log',
    'org.apache.commons.logging.LogFactory',

    // from Log4j (deliberate, Netty will fallback to Log4j 2)
    'org.apache.log4j.Level',
    'org.apache.log4j.Logger',

    // from io.netty.handler.ssl.OpenSslEngine (netty)
    'io.netty.internal.tcnative.Buffer',
    'io.netty.internal.tcnative.CertificateCompressionAlgo',
    'io.netty.internal.tcnative.Library',
    'io.netty.internal.tcnative.SessionTicketKey',
    'io.netty.internal.tcnative.SSL',
    'io.netty.internal.tcnative.SSLContext',
    'io.netty.internal.tcnative.SSLPrivateKeyMethod',

    // from io.netty.handler.ssl.util.BouncyCastleSelfSignedCertGenerator (netty)
    'org.bouncycastle.cert.X509v3CertificateBuilder',
    'org.bouncycastle.cert.jcajce.JcaX509CertificateConverter',
    'org.bouncycastle.operator.jcajce.JcaContentSignerBuilder',
    'org.bouncycastle.openssl.PEMEncryptedKeyPair',
    'org.bouncycastle.openssl.PEMParser',
    'org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter',
    'org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder',
    'org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder',
    'org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo',

    // from io.netty.handler.ssl.JettyNpnSslEngine (netty)
    'org.eclipse.jetty.npn.NextProtoNego$ClientProvider',
    'org.eclipse.jetty.npn.NextProtoNego$ServerProvider',
    'org.eclipse.jetty.npn.NextProtoNego',

    // from io.netty.handler.codec.marshalling.ChannelBufferByteInput (netty)
    'org.jboss.marshalling.ByteInput',

    // from io.netty.handler.codec.marshalling.ChannelBufferByteOutput (netty)
    'org.jboss.marshalling.ByteOutput',

    // from io.netty.handler.codec.marshalling.CompatibleMarshallingEncoder (netty)
    'org.jboss.marshalling.Marshaller',

    // from io.netty.handler.codec.marshalling.ContextBoundUnmarshallerProvider (netty)
    'org.jboss.marshalling.MarshallerFactory',
    'org.jboss.marshalling.MarshallingConfiguration',
    'org.jboss.marshalling.Unmarshaller',

    // from io.netty.util.internal.logging.InternalLoggerFactory (netty) - it's optional
    'org.slf4j.helpers.FormattingTuple',
    'org.slf4j.helpers.MessageFormatter',
    'org.slf4j.Logger',
    'org.slf4j.LoggerFactory',
    'org.slf4j.spi.LocationAwareLogger',


    'com.google.protobuf.ExtensionRegistryLite',
    'com.google.protobuf.MessageLiteOrBuilder',
    'com.google.protobuf.nano.CodedOutputByteBufferNano',
    'com.google.protobuf.nano.MessageNano',
    'com.github.luben.zstd.Zstd',
    'com.github.luben.zstd.ZstdInputStreamNoFinalizer',
    'com.github.luben.zstd.util.Native',
    'com.jcraft.jzlib.Deflater',
    'com.jcraft.jzlib.Inflater',
    'com.jcraft.jzlib.JZlib$WrapperType',
    'com.jcraft.jzlib.JZlib',
    'com.ning.compress.BufferRecycler',
    'com.ning.compress.lzf.ChunkDecoder',
    'com.ning.compress.lzf.ChunkEncoder',
    'com.ning.compress.lzf.LZFChunk',
    'com.ning.compress.lzf.LZFEncoder',
    'com.ning.compress.lzf.util.ChunkDecoderFactory',
    'com.ning.compress.lzf.util.ChunkEncoderFactory',
    'lzma.sdk.lzma.Encoder',
    'io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod',
    'io.netty.internal.tcnative.AsyncTask',
    'io.netty.internal.tcnative.CertificateCallback',
    'io.netty.internal.tcnative.CertificateVerifier',
    'io.netty.internal.tcnative.SessionTicketKey',
    'io.netty.internal.tcnative.SniHostNameMatcher',
    'io.netty.internal.tcnative.SSL',
    'io.netty.internal.tcnative.SSLSession',
    'io.netty.internal.tcnative.SSLSessionCache',
    'io.netty.internal.tcnative.ResultCallback',
    'org.eclipse.jetty.alpn.ALPN$ClientProvider',
    'org.eclipse.jetty.alpn.ALPN$ServerProvider',
    'org.eclipse.jetty.alpn.ALPN',

    'org.conscrypt.AllocatedBuffer',
    'org.conscrypt.BufferAllocator',
    'org.conscrypt.Conscrypt',
    'org.conscrypt.HandshakeListener',

    'reactor.blockhound.BlockHound$Builder',
    'reactor.blockhound.integration.BlockHoundIntegration'
  )

  ignoreViolations(
    'io.netty.util.internal.PlatformDependent0',
    'io.netty.util.internal.PlatformDependent0$1',
    'io.netty.util.internal.PlatformDependent0$2',
    'io.netty.util.internal.PlatformDependent0$3',
    'io.netty.util.internal.PlatformDependent0$4',
    'io.netty.util.internal.PlatformDependent0$6',
    'io.netty.util.internal.shaded.org.jctools.queues.BaseLinkedQueueConsumerNodeRef',
    'io.netty.util.internal.shaded.org.jctools.queues.BaseLinkedQueueProducerNodeRef',
    'io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields',
    'io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields',
    'io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields',
    'io.netty.util.internal.shaded.org.jctools.queues.LinkedQueueNode',
    'io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField',
    'io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField',
    'io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField',
    'io.netty.util.internal.shaded.org.jctools.queues.MpmcArrayQueueConsumerIndexField',
    'io.netty.util.internal.shaded.org.jctools.queues.MpmcArrayQueueProducerIndexField',
    'io.netty.util.internal.shaded.org.jctools.queues.unpadded.MpscUnpaddedArrayQueueConsumerIndexField',
    'io.netty.util.internal.shaded.org.jctools.queues.unpadded.MpscUnpaddedArrayQueueProducerIndexField',
    'io.netty.util.internal.shaded.org.jctools.queues.unpadded.MpscUnpaddedArrayQueueProducerLimitField',
    'io.netty.util.internal.shaded.org.jctools.util.UnsafeAccess',
    'io.netty.util.internal.shaded.org.jctools.util.UnsafeRefArrayAccess',
    'io.netty.util.internal.shaded.org.jctools.util.UnsafeLongArrayAccess',
    'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator',
    'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$1',
    'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$2',
    'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$3',
    'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$4',
    'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator$5'
  )
}

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