/*
 * Copyright Thoughtworks, Inc.
 *
 * Licensed 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 com.thoughtworks.go.build.VerifyJarTask

description = 'GoCD Agent'

sourceSets {
  functionalTest {
    java {
      srcDirs = [file('src/test-functional/java')]
    }
    resources {
      srcDirs = [file('src/test-functional/resources')]
    }

    compileClasspath = sourceSets.main.output + sourceSets.test.output + configurations.functionalTestCompileClasspath
    runtimeClasspath = output + compileClasspath + configurations.functionalTestRuntimeClasspath
  }
}

idea {
  module {
    testSources.from(sourceSets.functionalTest.java.srcDirs)
  }
}

configurations {
  functionalTestCompileClasspath.extendsFrom testCompileClasspath
  functionalTestRuntimeClasspath.extendsFrom testRuntimeClasspath
  runtimeElements.extendsFrom packagingOnly
}

dependencies {
  implementation(project(':agent-common')) { capabilities { requireFeature('agent-client') } }
  runtimeOnly(project(':base')) { capabilities { requireFeature('agent-client') } }
  implementation project(':common')
  implementation project(':domain')
  implementation project(':plugin-infra:go-plugin-access')
  implementation project(':plugin-infra:go-plugin-infra')
  implementation project(':config:config-api')
  implementation project.deps.jakartaAnnotation
  implementation project.deps.commonsConfiguration
  implementation project.deps.commonsIO
  implementation project.deps.gson
  implementation project.deps.springContext
  implementation project.deps.oshi
  compileOnly project.deps.jetBrainsAnnotations

  implementation(project.deps.apacheHttpComponents) {
    exclude(module: 'commons-codec')
  }
  if (project.deps.apacheHttpComponents) {
    runtimeOnly project.deps.slf4jJcl // Allow commons-logging replacement
  }

  testImplementation(testFixtures(project(':test:test-utils')))

  testImplementation project.deps.junit5Api
  testRuntimeOnly project.deps.junit5Engine
  testRuntimeOnly project.deps.junit5PlatformLauncher
  testImplementation project.deps.junit5Params
  testImplementation project.deps.springTest
  testImplementation project.deps.springTestJunit5
  testImplementation project.deps.assertJ
  testImplementation project.deps.systemStubs
  testImplementation project.deps.mockitoCore
  testImplementation project.deps.mockitoJunit5

  functionalTestImplementation project.deps.apacheHttpComponents

  extractedAtTopLevel project(':agent-process-launcher')
  extractedAtTopLevel project(':jar-class-loader')
}

jar {
  archiveClassifier = 'classes'
}

clean {
  delete 'config'
  delete 'felix-cache'
  delete 'main'
  delete 'pipelines'
  delete 'plugins'
  delete 'plugins_work'
  delete 'agent-plugins.zip'
  delete 'tfs-impl.jar'
}

def fatJar = tasks.register('fatJar', Jar) {
  finalizedBy 'verifyJar'
  dependsOn jar, configurations.extractedAtTopLevel, configurations.packagingOnly, configurations.runtimeClasspath

  manifest {
    attributes 'Main-Class': 'com.thoughtworks.gocd.Boot'
    attributes 'GoCD-Main-Class': 'com.thoughtworks.go.agent.AgentMain'
    attributes 'Go-Agent-Bootstrap-Class': 'com.thoughtworks.go.agent.AgentProcessParentImpl'
  }

  from({ configurations.runtimeClasspath + configurations.packagingOnly + jar.archiveFile }) {
    into "lib/"
    rename "go-plugin-activator-${project.version}.jar", "go-plugin-activator.jar"
  }

  from({ configurations.extractedAtTopLevel.collect { it.isDirectory() ? it : zipTree(it) } }) {
    into("/")
  }
}

tasks.register('verifyJar', VerifyJarTask) {
  jarTask = fatJar
  expectedJars = [
    "lib": [
      "agent-${project.version}-classes.jar",
      "agent-common-${project.version}.jar",
      "angus-activation-2.0.3.jar",
      "animal-sniffer-annotations-1.9.jar",
      "ant-${project.versions.apacheAnt}.jar",
      "base-${project.version}.jar",
      "bcpkix-jdk18on-${project.versions.bouncyCastle}.jar",
      "bcprov-jdk18on-${project.versions.bouncyCastle}.jar",
      "bcutil-jdk18on-${project.versions.bouncyCastle}.jar",
      "cloning-${project.versions.cloning}.jar",
      "commandline-${project.version}.jar",
      "common-${project.version}.jar",
      "commons-codec-${project.versions.commonsCodec}.jar",
      "commons-collections4-${project.versions.commonsCollections4}.jar",
      "commons-configuration2-${project.versions.commonsConfiguration}.jar",
      "commons-io-${project.versions.commonsIO}.jar",
      "commons-lang3-${project.versions.commonsLang3}.jar",
      "commons-text-${project.versions.commonsText}.jar",
      "config-api-${project.version}.jar",
      "db-${project.version}.jar",
      "domain-${project.version}.jar",
      "go-plugin-access-${project.version}.jar",
      "go-plugin-activator.jar",
      "go-plugin-api-${project.version}.jar",
      "go-plugin-api-internal-${project.version}.jar",
      "go-plugin-domain-${project.version}.jar",
      "go-plugin-infra-${project.version}.jar",
      "gson-${project.versions.gson}.jar",
      "httpclient-${project.versions.apacheHttpComponents}.jar",
      "httpcore-4.4.16.jar",
      "httpmime-${project.versions.apacheHttpComponents}.jar",
      "istack-commons-runtime-4.1.2.jar",
      "jakarta.activation-api-2.1.4.jar",
      "jakarta.annotation-api-${project.versions.jakartaAnnotation}.jar",
      "jakarta.xml.bind-api-4.0.4.jar",
      "jaxb-core-${project.versions.jaxbBom}.jar",
      "jaxb-runtime-${project.versions.jaxbBom}.jar",
      "jcl-over-slf4j-${project.versions.slf4jBom}.jar",
      "jcommander-${project.versions.jcommander}.jar",
      "jdom2-${project.versions.jdom}.jar",
      "jna-jpms-5.17.0.jar",
      "jna-platform-jpms-5.17.0.jar",
      "logback-classic-${project.versions.logback}.jar",
      "logback-core-${project.versions.logback}.jar",
      "objenesis-${project.versions.objenesis}.jar",
      "org.apache.felix.framework-${project.versions.felix}.jar",
      "oshi-core-java11-${project.versions.oshi}.jar",
      "plugin-metadata-store-${project.version}.jar",
      "semantic-version-${project.versions.semanticVersion}.jar",
      "slf4j-api-${project.versions.slf4jBom}.jar",
      "spring-aop-${project.versions.spring}.jar",
      "spring-beans-${project.versions.spring}.jar",
      "spring-context-${project.versions.spring}.jar",
      "spring-core-${project.versions.spring}.jar",
      "spring-expression-${project.versions.spring}.jar",
      "spring-tx-${project.versions.spring}.jar",
      "spring-web-${project.versions.spring}.jar",
      "txw2-${project.versions.jaxbBom}.jar",
      "util-${project.version}.jar"
    ]
  ]
}

tasks.register('functionalTest', Test) {
  description = 'Runs the functional tests.'
  group = 'verification'
  testClassesDirs = sourceSets.functionalTest.output.classesDirs
  classpath = sourceSets.functionalTest.runtimeClasspath
  mustRunAfter test

  reports {
    html.required = true
    junitXml.required = true
  }
}

check.dependsOn(functionalTest)

artifacts {
  fatJarConfig fatJar
}
