/*
 * 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 org.ajoberstar.grgit.Grgit
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.regex.Pattern
import net.ltgt.gradle.errorprone.CheckSeverity

buildscript {
  repositories {
    jcenter() // jcenter
  }

  dependencies { classpath "org.ajoberstar.grgit:grgit-core:3.1.1" }
}

plugins {
  id 'com.diffplug.gradle.spotless' version '3.28.1'
  id 'net.ltgt.errorprone' version '1.2.1'
  id 'io.spring.dependency-management' version '1.0.6.RELEASE'
  id 'com.github.hierynomus.license' version '0.15.0'
  id 'org.gradle.crypto.checksum' version '1.1.0'
  id 'org.jetbrains.kotlin.jvm' version '1.3.30'
  id 'org.jetbrains.dokka' version "0.10.1"
  id 'maven-publish'
  id 'com.jfrog.bintray' version '1.8.3'
}

description = 'A set of libraries and other tools to aid development of blockchain and other decentralized software in Java and other JVM languages'

//////
// Version numbering

def versionNumber = '1.3.0'
def buildVersion = versionNumber + buildTag()

static String buildTag() {
  if (System.getenv('BUILD_RELEASE') == 'true') {
    return ''
  }
  if (System.getenv('BUILD_TIMESTAMP') != null) {
    return DateTimeFormatter.ofPattern("-yyyyMMddHHmmss").withLocale(Locale.US).withZone( ZoneId.systemDefault() ).format(Instant.now())
  }
  return '-SNAPSHOT'
}


//////
// Default tasks and build aliases

defaultTasks 'checkLicenses', 'spotlessCheck', 'jar', 'test', ':javadoc'

def buildAliases = ['dev': [
    'spotlessApply',
    'checkLicenses',
    ':jar',
    'test',
    ':javadoc'
  ]]

def expandedTaskList = []
gradle.startParameter.taskNames.each {
  expandedTaskList << (buildAliases[it] ? buildAliases[it] : it)
}
gradle.startParameter.taskNames = expandedTaskList.flatten()

apply from: "${rootDir}/wrapper.gradle"

apply from: "${rootDir}/gradle/stage.gradle"

//////
// RAT checks

if (file('.git').exists()) {
  apply from: "${rootDir}/gradle/rat.gradle"
  rat {
    // Exclude everything under the directory that git should be ignoring via .gitignore or that isn't checked in. These
    // restrict us only to files that are checked in or are staged.
    def repo = Grgit.open(currentDir: project.getRootDir())
    excludes = {
      def list = new ArrayList<String>(repo.clean(ignore: false, directories: true, dryRun: true))
      // And some of the files that we have checked in should also be excluded from this check
      list.addAll([
        '.*\\.asc',
        'gradle/tuweni-test.asc',
        '\\w+/out/.*',
        'eth-reference-tests/**',
        'build',
        '.*/build/**',
        '.editorconfig',
        '.idea/**',
        'gradlew.bat',
        'gradlew',
        'toml/src/test/resources/**',
        '.gitattributes',
        '.*\\.kotlin_module',
        'example-v0.4.0.toml',
        'hard_example.toml',
        'toml-v0.5.0-spec-example.toml',
        'eth2-reference-tests/**',
        'package-lock.json',
        '.github/pull_request_template.md',
        'devp2p-eth/src/test/resources/mainnet.json',
        'devp2p-eth/src/test/resources/besu-dev.json',
        'eth/src/test/resources/mainnet.json',
        'eth-client/src/main/resources/mainnet.json',
        'eth-client/src/main/resources/default.json',
        'eth/src/test/resources/missing-difficulty.json',
        'eth/src/test/resources/missing-nonce.json',
        'eth/src/test/resources/valid-genesis.json',
        'eth/src/test/resources/besu-dev.json',
        'eth-client-app/src/main/resources/tuweni.txt',
        'evm/src/test/resources/VMTests/**',
        'tuweni.png'
      ])
      return list
    }
  }
  spotlessCheck.dependsOn rat
}

//////
// Gradle script formatting

spotless {
  groovyGradle {
    target '**/*.gradle'
    greclipse().configFile(rootProject.file('gradle/greclipse-gradle-tuweni-style.properties'))
    endWithNewline()
  }
}

task integrationTest(type: Test) {
}

subprojects {

  //////
  // Source formatting

  apply plugin: 'com.diffplug.gradle.spotless'
  spotless {
    java {
      target project.fileTree(project.projectDir) {
        include '**/*.java'
        exclude '**/generated-src/**/*.*'
        exclude '**/SECP256K1.java'
      }
      removeUnusedImports()
      licenseHeaderFile rootProject.file('gradle/spotless.license.txt')
      eclipse().configFile(rootProject.file('gradle/eclipse-java-tuweni-style.xml'))
      importOrder 'org.apache', 'java', ''
      endWithNewline()
    }
    kotlin {
      licenseHeaderFile rootProject.file('gradle/spotless.license.txt')
      ktlint().userData(['indent_size': '2', 'continuation_indent_size' : '2', 'max_line_length': '120', 'disabled_rules': 'import-ordering'])
      endWithNewline()
    }
  }

  plugins.withId('java', { _ ->
    sourceSets {
      integrationTest {
        compileClasspath += sourceSets.main.output + sourceSets.test.output
        runtimeClasspath += sourceSets.main.output + sourceSets.test.output
      }
    }

    configurations {
      integrationTestImplementation.extendsFrom testImplementation
      integrationTestRuntime.extendsFrom testRuntime
    }
    dependencies {
      integrationTestRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
      integrationTestRuntimeOnly 'ch.qos.logback:logback-classic'
    }

    task integrationTest(type: Test) {
      description = 'Runs integration tests.'
      group = 'verification'

      testClassesDirs = sourceSets.integrationTest.output.classesDirs
      classpath = sourceSets.integrationTest.runtimeClasspath

      useJUnitPlatform() { includeEngines 'spek', 'junit-jupiter' }
      timeout = Duration.ofMinutes(30)

    }

    rootProject.integrationTest.dependsOn integrationTest
  })

  //////
  // Parallel build execution

  tasks.withType(Test) {
    // If GRADLE_MAX_TEST_FORKS is not set, use half the available processors
    maxParallelForks = (System.getenv('GRADLE_MAX_TEST_FORKS') ?:
      (Runtime.runtime.availableProcessors().intdiv(2) ?: 1)).toInteger()
  }

  tasks.withType(JavaCompile) {
    options.fork = true
    options.incremental = true
    options.encoding = 'UTF-8'
  }

  task allDependencies(type: DependencyReportTask) {}
}

//////
// Project defaults

allprojects {
  apply plugin: 'java-library'
  apply plugin: 'kotlin'
  apply plugin: 'io.spring.dependency-management'
  apply plugin: 'jacoco'
  apply plugin: 'org.jetbrains.dokka'
  apply plugin: 'com.jfrog.bintray'
  apply plugin: 'net.ltgt.errorprone'
  apply plugin: 'maven-publish'
  apply plugin: 'signing'
  apply from: "${rootDir}/dependency-versions.gradle"
  apply from: "${rootDir}/gradle/check-licenses.gradle"

  version = buildVersion

  repositories {
    jcenter()
    maven {
      url "https://dl.bintray.com/tuweni/evmc"
    }
  }


  //////
  // Compiler arguments

  sourceCompatibility = '1.11'
  targetCompatibility = '1.11'

  dependencies {
    errorprone 'com.google.errorprone:error_prone_core'
    if (JavaVersion.current().isJava8()) {
      errorproneJavac("com.google.errorprone:javac")
    }
  }

  tasks.withType(AbstractArchiveTask) {
    preserveFileTimestamps = false
    reproducibleFileOrder = true
  }

  tasks.withType(JavaCompile) {
    options.compilerArgs += [
      '-Xlint:unchecked',
      '-Xlint:cast',
      '-Xlint:rawtypes',
      '-Xlint:overloads',
      '-Xlint:divzero',
      '-Xlint:finally',
      '-Xlint:static',
      '-Werror'
    ]

    options.errorprone {
      excludedPaths = '.*/generated-src/.*'
      check('FutureReturnValueIgnored', CheckSeverity.OFF)
      check('UnnecessaryParentheses', CheckSeverity.OFF)

      // This check is broken in Java 12.  See https://github.com/google/error-prone/issues/1257
      if (JavaVersion.current() == JavaVersion.VERSION_12) {
        check('Finally', CheckSeverity.OFF)
      }

      // This check is broken after Java 12.  See https://github.com/google/error-prone/issues/1352
      if (JavaVersion.current() > JavaVersion.VERSION_12) {
        check('TypeParameterUnusedInFormals', CheckSeverity.OFF)
      }

      disableWarningsInGeneratedCode = true
    }
  }

  tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
    kotlinOptions {
      jvmTarget = "11"
      allWarningsAsErrors = true
      freeCompilerArgs = [
        '-Xjsr305=strict',
        '-Xjvm-default=enable',
        '-Xuse-experimental=kotlin.Experimental'
      ]
    }
  }


  //////
  // Use JUnit5 for testing

  test {
    useJUnitPlatform() { includeEngines 'spek', 'junit-jupiter' }
    timeout = Duration.ofMinutes(30)
  }

  jacocoTestReport {
    reports {
      xml.enabled true
      html.enabled true
    }
    getExecutionData().setFrom(fileTree(buildDir).include("/jacoco/*.exec"))
  }


  //////
  // Documentation

  dokka {
    outputFormat = 'html'
    configuration {
      noStdlibLink = true
      noJdkLink = true
      jdkVersion = 11
      includeNonPublic = false
      def relativePath = rootDir.toPath().relativize(projectDir.toPath()).toString()
      sourceLink {
        path = projectDir.toString()
        url = "https://github.com/apache/incubator-tuweni/blob/master/$relativePath"
        lineSuffix = "#L"
      }
    }
  }


  //////
  // Artifact locations

  jar {
    destinationDirectory = file("${rootProject.buildDir}/libs")
  }

  task sourcesJar(type: Jar, dependsOn: classes) {
    destinationDirectory = file("${rootProject.buildDir}/src")
    classifier = 'sources'
    from sourceSets.main.allSource
  }

  //////
  // Packaging and deployment

  tasks.withType(Jar) {
    if (rootProject == project) {
      archiveBaseName = project.name
    } else {
      archiveBaseName = rootProject.name + '-' + project.name
    }
    manifest {
      attributes('Implementation-Title': archiveBaseName,
      'Implementation-Version': project.version)
    }
    from(rootProject.projectDir) {
      include 'DISCLAIMER'
      include 'LICENSE'
      include 'NOTICE'
      into 'META-INF'
    }
  }

  if (project.name != 'eth-reference-tests' && project.name != 'eth2-reference-tests' && project.name != 'dist') {

    artifacts {
      archives sourcesJar
      archives jar
    }

    signing {
      useGpgCmd()
      sign configurations.archives
    }

    publishing {
      repositories {
        maven {
          def isRelease = buildVersion.endsWith('SNAPSHOT')
          def releasesRepoUrl = "https://repository.apache.org/service/local/staging/deploy/maven2"
          def snapshotsRepoUrl = "https://repository.apache.org/content/repositories/snapshots"
          url = isRelease ? snapshotsRepoUrl : releasesRepoUrl

          def settingsXml = new File(System.getProperty('user.home'), '.m2/settings.xml')

          def credentialsFound = false;
          if (settingsXml.exists()) {
            project.logger.info('Reading .m2/settings.xml')
            def serverId = (project.properties['distMgmtServerId'] ?: isRelease
              ? 'apache.releases.https' : 'apache.snapshots.https')
            def m2SettingCreds = new XmlSlurper().parse(settingsXml).servers.server.find { server -> serverId.equals(server.id.text()) }
            if (m2SettingCreds) {
              project.logger.info('Found matching credentials from .m2/settings.xml')
              credentials {
                username m2SettingCreds.username.text()
                password m2SettingCreds.password.text()
              }
              credentialsFound = true
            }
          }

          if (!credentialsFound) {
            project.logger.info('Reading credentials from environment')
            project.logger.info('Username ' + asfNexusUsername)
            credentials {
              username asfNexusUsername
              password asfNexusPassword
            }
          }
        }
      }
      publications {
        MavenDeployment(MavenPublication) { publication ->
          if (project != rootProject) {
            from components.java
            artifact sourcesJar { classifier 'sources' }
          }
          groupId 'org.apache.tuweni'
          artifactId project.name
          version project.version

          versionMapping {
            usage('java-runtime'){
              fromResolutionResult()
            }
            usage('java-api'){
              fromResolutionResult()
            }
          }

          pom {
            name = project.name
            afterEvaluate { description = project.description }
            url = 'https://github.com/apache/incubator-tuweni'
            licenses {
              license {
                name = "The Apache License, Version 2.0"
                url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
              }
            }
            scm {
              connection = 'scm:https://github.com/apache/incubator-tuweni.git'
              developerConnection = 'scm:git@github.com:apache/incubator-tuweni.git'
              url = 'https://github.com/apache/incubator-tuweni'
            }
            developers {
              developer {
                name = 'Antoine Toulme'
                email = 'antoine@lunar-ocean.com'
                organization = 'Apache'
                organizationUrl = 'https://tuweni.apache.org'
              }
              developer {
                name = 'Jonny Rhea'
                organization = 'Apache'
                organizationUrl = 'https://tuweni.apache.org'
              }
              developer {
                name = 'Steven J Schroeder'
                email = 'sjs@apache.org'
                organization = 'Apache'
                organizationUrl = 'https://tuweni.apache.org'
              }
            }
            issueManagement {
              system = "jira"
              url = "https://issues.apache.org/jira/projects/TUWENI"
            }
          }

          pom.withXml {
            // use inline versions rather than pom dependency management
            asNode().remove(asNode().dependencyManagement[0])
            if (asNode().dependencies[0]) {
              asNode().remove(asNode().dependencies[0])
            }

            def dependenciesNode = asNode().appendNode('dependencies')
            def addDependencyNode = { dep, optional ->
              def dependencyNode = dependenciesNode.appendNode('dependency')
              if (dep instanceof ProjectDependency) {
                dependencyNode.appendNode('groupId', 'org.apache.tuweni')
                dependencyNode.appendNode('artifactId', rootProject.name + '-' + dep.name)
                dependencyNode.appendNode('version', dep.version)
              } else {
                dependencyNode.appendNode('groupId', dep.group)
                dependencyNode.appendNode('artifactId', dep.name)
                if (dep.version != null) {
                  dependencyNode.appendNode('version', dep.version)
                } else {
                  def version = dependencyManagement.managedVersions["$dep.group:$dep.name"]
                  dependencyNode.appendNode('version', version)
                }
              }
              if (optional) {
                dependencyNode.appendNode('optional', 'true')
              }

              def ers = dep.excludeRules
              if (!ers.empty) {
                def exclusionsNode = dependencyNode.appendNode('exclusions')
                ers.each { er ->
                  def exclusionNode = exclusionsNode.appendNode('exclusion')
                  exclusionNode.appendNode('groupId', er.group)
                  exclusionNode.appendNode('artifactId', er.module)
                }
              }
            }

            configurations.compile.allDependencies.each { dep ->
              addDependencyNode(dep, false)
            }
            configurations.compileOnly.allDependencies.each { dep ->
              addDependencyNode(dep, true)
            }

            if (System.getenv('ENABLE_SIGNING') == 'true') {
              def pomFile = file("${project.buildDir}/generated-pom.xml")
              writeTo(pomFile)
              def pomAscFile = signing.sign(pomFile).signatureFiles[0]
              artifact(pomAscFile) {
                classifier = null
                extension = 'pom.asc'
              }
            }
          }

          if (System.getenv('ENABLE_SIGNING') == 'true') {
            // create the signed artifacts
            tasks.signArchives.signatureFiles.each {
              artifact(it) {
                def matcher = it.file =~ /-(sources|javadoc)\.jar\.asc$/
                if (matcher.find()) {
                  classifier = matcher.group(1)
                } else {
                  classifier = null
                }
                extension = 'jar.asc'
              }
            }
          }
        }
      }
    }

    tasks.withType(Sign) {
      onlyIf {
        System.getenv('ENABLE_SIGNING') == 'true'
      }
    }

    tasks.withType(GenerateModuleMetadata) {
      enabled = false
    }

    model {
      tasks.generatePomFileForMavenDeploymentPublication {
        destination = file("$buildDir/generated-pom.xml")
      }
      tasks.publishMavenDeploymentPublicationToMavenLocal { dependsOn project.tasks.signArchives }
    }

    bintray {
      publications = ['MavenDeployment']
      user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : 'invalid'
      key = project.hasProperty('bintrayKey') ? project.property('bintrayKey') : 'invalid'
      pkg {
        repo = project.hasProperty('bintrayRepo') ? project.property('bintrayRepo') : 'invalid'
        name = project.hasProperty('bintrayName') ? project.property('bintrayName') : 'invalid'
        userOrg = project.hasProperty('bintrayOrg') ? project.property('bintrayOrg') : 'invalid'
        licenses = ['Apache-2.0']
        vcsUrl = 'https://github.com/apache/incubator-tuweni.git'
      }
    }
  }
}


//////
// Configure root project as a virtual package that depends on all components

dependencies {
  subprojects.findAll {
    !it.name.contains('reference-tests')
  }.each { p ->
    switch (p.name) {
      case 'crypto':
        implementation(p) {
          exclude group: 'com.github.jnr', module: 'jnr-ffi'
        }
        break
      default:
        implementation p
        break
    }
  }
}

apply plugin: 'kotlin'
apply plugin: 'org.jetbrains.dokka'

dokka {
  outputDirectory = "$rootProject.buildDir/docs"
  // In case of a Gradle multiproject build, you can include subprojects here to get merged documentation
  // Note however, that you have to have the Kotlin plugin available in the root project and in the subprojects
  subProjects = project.subprojects.collect { it.name }

  // Used for disabling auto extraction of sources and platforms in both multi-platform and single-platform modes
  // When set to true, subProject and kotlinTasks are also omitted
  disableAutoconfiguration = false

  // Use default or set to custom path to cache directory
  // to enable package-list caching
  // When this is set to default, caches are stored in $USER_HOME/.cache/dokka
  cacheRoot = 'default'

  configuration {
    moduleName = 'tuweni'

    // Use to include or exclude non public members.
    includeNonPublic = false

    // Do not output deprecated members. Applies globally, can be overridden by packageOptions
    skipDeprecated = false

    // Emit warnings about not documented members. Applies globally, also can be overridden by packageOptions
    reportUndocumented = true
    // will come out in next version
    // failOnWarning = true

    // Do not create index pages for empty packages
    skipEmptyPackages = true

    // Platform used for code analysis. See the "Platforms" section of this readme
    platform = "JVM"

    // List of files with module and package documentation
    // https://kotlinlang.org/docs/reference/kotlin-doc.html#module-and-package-documentation
    includes = ['docs.md']

    // Specifies the location of the project source code on the Web.
    // If provided, Dokka generates "source" links for each declaration.
    // Repeat for multiple mappings
    sourceLink {
      // Unix based directory relative path to the root of the project (where you execute gradle respectively).
      path = rootDir.toString()

      // URL showing where the source code can be accessed through the web browser
      url = "https://github.com/apache/incubator-tuweni" //remove src/main/kotlin if you use "./" above

      // Suffix which is used to append the line number to the URL. Use #L for GitHub
      lineSuffix = "#L"
    }

    // Used for linking to JDK documentation
    jdkVersion = 11

    // Disable linking to online kotlin-stdlib documentation
    noStdlibLink = true

    // Disable linking to online JDK documentation
    noJdkLink = true

    // Those packages are not ready yet, skipping their docs.
    perPackageOption {
      prefix = "org.apache.tuweni.peer.repository"
      reportUndocumented = false
    }
    perPackageOption {
      prefix = "org.apache.tuweni.ethclientui"
      reportUndocumented = false
    }
    perPackageOption {
      prefix = "org.apache.tuweni.ethclient"
      reportUndocumented = false
    }
    perPackageOption {
      prefix = "org.apache.tuweni.devp2p.eth"
      reportUndocumented = false
    }
  }
}
