/*
 * 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.16.0'
  id 'net.ltgt.errorprone' version '0.6'
  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.20'
  id 'org.jetbrains.dokka' version '0.9.17'
  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'

//////
// Sanity checks
if (!file("${rootDir}/eth-reference-tests/src/test/resources/eth2.0-tests/README.md").exists()) {
  throw new GradleException("eth-reference-tests/src/test/resources/eth2.0-tests/README.md missing: please clone submodules (git submodule update --init --recursive)")
}


//////
// Version numbering

def versionNumber = '0.9.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',
        '\\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',
      ])
      return list
    }
  }
}

//////
// Gradle script formatting

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


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'])
      endWithNewline()
    }
  }


  //////
  // 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.8'
  targetCompatibility = '1.8'

  jacoco { toolVersion = '0.8.2' }

  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) {
    // Until https://github.com/gradle/gradle/issues/2510 is resolved and
    // something like a `releaseCompability` property is added, we have to add
    // the --release flag explicitly
    if (JavaVersion.current() > JavaVersion.VERSION_1_8) {
      options.compilerArgs.addAll(['--release', '8'])
    }
    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)
      disableWarningsInGeneratedCode = true
    }
  }

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


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

  test { useJUnitPlatform() { includeEngines 'spek', 'junit-jupiter' } }


  //////
  // Documentation

  dokka {
    outputFormat = 'html'
    outputDirectory = "$buildDir/docs/dokka"
    jdkVersion = 8
    includeNonPublic = false
    def relativePath = rootDir.toPath().relativize(projectDir.toPath()).toString()
    linkMapping {
      dir = projectDir.toString()
      url = "https://github.com/apache/incubator-tuweni/blob/master/$relativePath"
      suffix = "#L"
    }
  }


  //////
  // Artifact locations

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

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

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

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


  //////
  // Packaging and deployment

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

  if (project.name != 'eth-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

          pom {
            name = project.jar.baseName
            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'
      }
    }

    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.each { p ->
    switch (p.name) {
      case 'eth-reference-tests':
      // ignore
        break
      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') {
      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 {
  moduleName = rootProject.name
  subprojects.each {
    dependsOn it.classes
    it.sourceSets.main.output.each { d ->
      if (d.exists()) {
        classpath += d
      }
    }
  }
  sourceDirs = files(subprojects.collect {
    return [
      new File(it.projectDir, '/src/main/kotlin'),
      new File(it.projectDir, '/src/main/java')
    ]
  })
  linkMapping {
    dir = rootDir.toString()
    url = "https://github.com/apache/incubator-tuweni/blob/master"
    suffix = "#L"
  }

  includes = ['PACKAGES.md']

  externalDocumentationLink {
    url = new URL("https://docs.oracle.com/javase/8/docs/api/")
  }

  externalDocumentationLink {
    url = new URL('https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/')
  }
}

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