/*
 * 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 com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import org.gradle.crypto.checksum.Checksum

plugins { id 'com.bmuschko.docker-remote-api' version '6.7.0' }

description = 'Tuweni distribution.'

apply plugin: 'distribution'

jar { enabled = false }

task createBinaryLicense {
  description "Create a LICENSE file with all dependencies"

  doLast {
    new File("$project.buildDir/license").mkdirs()
    def binaryLicenseFile = new File("$project.buildDir/license/LICENSE")
    binaryLicenseFile.write(new File("$rootProject.projectDir/LICENSE").text)
    binaryLicenseFile.append(new File("$project.projectDir/LICENSE-binary").text)
  }
}

task createBinaryNotice {
  description "Create a NOTICE file with all dependencies"

  doLast {
    new File("$project.buildDir/notice").mkdirs()
    def binaryNoticeFile = new File("$project.buildDir/notice/NOTICE")
    binaryNoticeFile.write(new File("$rootProject.projectDir/NOTICE").text)
    binaryNoticeFile.append(new File("$project.projectDir/NOTICE-binary").text)
  }
}

static def mandatoryFiles(CopySpec spec) {
  spec.into('') {
    from ".."
    include 'DISCLAIMER'
  }
  spec.into('license-reports') { from '../build/dependency-license' }
}

task builtGradleProperties()  {
  doLast {
    project.buildDir.mkdirs()
    new File(project.buildDir, "gradle.properties").text = """
# 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.
buildRelease=true
kotlin.code.style=official
asfNexusUsername=none
asfNexusPassword=
org.gradle.jvmargs=-Xmx2048m \
  --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
  --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
  --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
  --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
  --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
"""
  }
}

assemble.dependsOn builtGradleProperties
assemble.dependsOn rootProject.generateLicenseReport
assemble.dependsOn createBinaryLicense
assemble.dependsOn createBinaryNotice

distributions {
  main {
    distributionBaseName = 'tuweni-bin'
    contents {
      duplicatesStrategy = DuplicatesStrategy.EXCLUDE
      mandatoryFiles(it)
      into('') {
        from ".."
        include 'README.md'
      }
      into('license-reports') {
        from "netty-license"
        include "*"
      }
      into('') {
        from "$project.buildDir/license"
        include 'LICENSE'
      }
      into('') {
        from "$project.buildDir/notice"
        include 'NOTICE'
      }
      def libs = []
      def sources = []
      rootProject.subprojects.each { s ->
        if (s.name != 'eth-reference-tests' && s.name != 'eth2-reference-tests' && s.name != 'dist') {
          libs << s.signArchives.signatureFiles[0]
          sources << s.signArchives.signatureFiles[1]
          libs << s.jar.outputs
          sources << s.sourcesJar.outputs
        }
      }
      into('lib') {
        from rootProject.jar
        from rootProject.signArchives.signatureFiles[0]
        from libs.unique(false)
      }

      into('bin') {
        from { project(':gossip').startScripts.outputs.files }
        from { project(':hobbits-relayer').startScripts.outputs.files }
        from { project(':eth-client-app').startScripts.outputs.files }
        from { project(':devp2p').startScripts.outputs.files }
        from { project(':eth-faucet').startScripts.outputs.files }
        from { project(':eth-crawler').startScripts.outputs.files }
        from { project(':jsonrpc-app').startScripts.outputs.files }
        from { project(':stratum:proxy').startScripts.outputs.files }
        fileMode = 0755
      }
    }
  }
  sources {
    distributionBaseName = 'tuweni-src'
    contents {
      duplicatesStrategy = DuplicatesStrategy.EXCLUDE
      into('') {
        from 'build'
        include 'gradle.properties'
      }
      mandatoryFiles(it)
      into('') {
        from ".."
        include 'LICENSE'
        include 'NOTICE'
        include 'README.md'
        include 'gradlew'
        include 'gradlew.bat'
        include '*.md'
        include '*.gradle'
        include 'dependency-versions.gradle'
        include 'gradle/resources/*'
        include 'dist/LICENSE-binary'
        include 'dist/NOTICE-binary'
        include 'gradle/*'
        include 'gradle/docker/*'
        include 'gradle/wrapper/gradle-wrapper.properties'
      }
      rootProject.subprojects.each { s ->
        def sPath = rootProject.projectDir.toPath().relativize(s.projectDir.toPath()).toString()
        into(sPath) {
          from s.projectDir.toPath().resolve("build.gradle")
        }
        into("${sPath}/src") {
          from s.projectDir.toPath().resolve("src")
        }
      }
    }
  }
}

task addDependencies() {
  doLast {
    def deps = []
    rootProject.subprojects.each { s ->
      s.configurations.runtimeClasspath.each {
        if (!it.toString().contains("libs/tuweni")) {
          deps << it
        }
      }
    }
    deps = deps.unique()

    distributions.main.contents.into('lib') {
      from(deps)
    }
  }
}

distZip.dependsOn addDependencies
distTar.dependsOn addDependencies


rootProject.subprojects.each {
  if (it != project) {
    project.distZip.dependsOn it.assemble
    project.distTar.dependsOn it.assemble
    project.sourcesDistZip.dependsOn it.sourcesJar
    project.sourcesDistTar.dependsOn it.sourcesJar
  }
}

sourcesDistZip { zip64 = true }

distTar { compression = Compression.GZIP }

sourcesDistTar { compression = Compression.GZIP }

if (System.getenv('ENABLE_SIGNING') == 'true') {
  signing {
    useGpgCmd()
    sign distZip
    sign distTar
    sign sourcesDistZip
    sign sourcesDistTar
  }
}

task createChecksums(type: Checksum, dependsOn: [
  'distZip',
  'distTar',
  'sourcesDistZip',
  'sourcesDistTar',
]) {
  files = distZip.outputs.files + distTar.outputs.files + sourcesDistZip.outputs.files + sourcesDistTar.outputs.files
  outputDir = new File(project.buildDir, "distributions")
  algorithm = Checksum.Algorithm.SHA512
}

build.dependsOn('createChecksums')

task buildBinImage(type: DockerBuildImage) {
  dependsOn distTar
  inputDir = projectDir
  dockerFile = file("docker/tuweni.Dockerfile")
  images = [
    "apache-tuweni/tuweni:$project.version"
  ]
}

integrationTest.dependsOn build

dependencies {
  integrationTestImplementation 'org.junit.jupiter:junit-jupiter-api'
  integrationTestImplementation 'org.junit.jupiter:junit-jupiter-params'

  integrationTestRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
