/*
 * 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.0'
  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.1.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',
        'eth/src/test/resources/mainnet.json',
        'eth-client/src/main/resources/mainnet.json',
        'eth/src/test/resources/missing-difficulty.json',
        'eth/src/test/resources/missing-nonce.json',
        'eth/src/test/resources/valid-genesis.json'
      ])
      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 {
      integrationTestRuntime 'org.junit.jupiter:junit-jupiter-engine'
      integrationTestRuntime '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: 'com.jfrog.bintray'
  apply plugin: 'net.ltgt.errorprone'
  apply plugin: 'maven-publish'
  apply plugin: 'org.jetbrains.dokka'
  apply plugin: 'signing'
  apply from: "${rootDir}/dependency-versions.gradle"
  apply from: "${rootDir}/gradle/check-licenses.gradle"

  version = buildVersion

  repositories { jcenter() }


  //////
  // 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
    }

    jacocoTestReport {
      reports {
        xml.enabled true
        html.enabled 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'
      ]
    }

    jacocoTestReport {
      reports {
        xml.enabled true
        html.enabled true
      }
    }
  }


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

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


  //////
  // Documentation

  dokka {
    outputFormat = 'html'
    outputDirectory = "$buildDir/docs/dokka"
    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
  }

  task javadocJar(type: Jar, dependsOn: javadoc) {
    destinationDirectory = file("${rootProject.buildDir}/docs")
    classifier = 'javadoc'
    from javadoc.outputDirectory
  }

  task dokkaJar(type: Jar, dependsOn: dokka) {
    destinationDirectory = file("${rootProject.buildDir}/docs")
    classifier = 'dokka'
    from dokka.outputDirectory
  }


  //////
  // 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
      archives dokkaJar
    }

    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' }
          }
          artifact dokkaJar { classifier 'javadoc' }
          groupId 'org.apache.tuweni'
          artifactId project.jar.baseName
          version project.version

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

          pom {
            name = project.jar.archiveBaseName.toString()
            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':
        compile(p) {
          exclude group: 'com.github.jnr', module: 'jnr-ffi'
        }
        break
      default:
        compile p
        break
    }
  }
}

jar {
  subprojects.each { subproject ->
    if (subproject.name != 'eth-reference-tests' && subproject.name != 'eth2-reference-tests') {
      from subproject.configurations.archives.collect { it.path.endsWith('.jar') }.files.collect { zipTree(it) }
    }
  }
}

javadoc {
  subprojects.each {
    source += it.javadoc.source
    classpath += it.javadoc.classpath
  }
}

dokka {

  configuration {
    noStdlibLink = true
    noJdkLink = true
    moduleName = rootProject.name
    subprojects.each {
      dependsOn it.classes
      it.sourceSets.main.output.each { d ->
        if (d.exists()) {
          classpath += d
        }
      }
    }

    sourceLink {
      path = rootDir.toString()
      url = "https://github.com/apache/incubator-tuweni/blob/master"
      lineSuffix = "#L"
    }

    includes = ['PACKAGES.md']
  }
}

dokkaJar {
  archiveBaseName = rootProject.name
  manifest {
    attributes('Implementation-Title': archiveBaseName,
    'Implementation-Version': project.version)
  }
}
