/*
 * 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.
 */

plugins {
    id "org.nosphere.apache.rat" version "0.6.0"
    id "com.diffplug.gradle.spotless" version "3.0.0"
    id "de.undercouch.download" version "3.1.2"
}

allprojects {
    repositories {
        if (!gradle.usingGeodeCompositeBuild) {
          maven {
            url project.findProperty('geodeRepositoryUrl') ?: 'https://maven.apachegeode-ci.info/snapshots'
            content {
              includeGroup 'org.apache.geode'
            }
          }
        }
        mavenCentral()
    }
}

def installDir = "$buildDir/apache-geode"

configurations {
    geodeDistribution
}

dependencies {
    geodeDistribution("org.apache.geode:apache-geode:$geodeVersion@tgz") {
      if (gradle.usingGeodeCompositeBuild) {
        targetConfiguration = 'compositeTarget'
      }
    }
}

task installGeode(type: Copy) {
    if (gradle.usingGeodeCompositeBuild) {
        dependsOn(gradle.includedBuild('geode').task(':geode-assembly:distTar'))
    }
    from {
        tarTree(configurations.geodeDistribution.singleFile)
    }
    eachFile { fcp ->
        fcp.path = fcp.path.replaceFirst("^apache-geode-[a-zA-Z0-9\\.\\-]+\\/", "apache-geode/")
    }
    into buildDir
    includeEmptyDirs false
}

subprojects {
    apply plugin: 'java-library'

    dependencies {
        // All callouts to org.apache.geode here, need to be specified in settings.gradle
        // for composite build to work
        api(platform("org.apache.geode:geode-all-bom:$geodeVersion"))
        implementation("org.apache.geode:geode-core")
        implementation("org.apache.geode:geode-cq")
        implementation("org.apache.geode:geode-logging")
        implementation('com.google.guava:guava')
        implementation('org.apache.commons:commons-lang3')
        implementation("org.apache.logging.log4j:log4j-core")

        testImplementation("org.awaitility:awaitility")
        testImplementation("junit:junit")
        testImplementation("org.mockito:mockito-core")
        testImplementation("com.github.stefanbirkner:system-rules")
        testImplementation("org.assertj:assertj-core")
        testImplementation('org.apache.httpcomponents:httpcore')
        testImplementation('org.apache.httpcomponents:httpclient')
        runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl"
    }

    jar {
        archiveName "${baseName}.${extension}"
    }

    task cleanServer {
        doLast {
            delete 'locator'
            delete 'locator-ln'
            delete 'locator-ny'
            delete 'server1'
            delete 'server2'
            delete 'server-ln-1'
            delete 'server-ln-2'
            delete 'server-ny-1'
            delete 'server-ny-2'
        }
    }
    clean.finalizedBy cleanServer

    def geodePath = "${System.env.PATH}${System.getProperty('path.separator')}${installDir}/bin"
    task start(type: Exec, dependsOn: [installGeode, build, cleanServer]) {
        workingDir projectDir
        environment 'GEODE_HOME', installDir
        environment 'PATH', geodePath
        commandLine 'sh', '-c', "gfsh run --file=${projectDir}/scripts/start.gfsh"
    }

    task stop(type: Exec, dependsOn: installGeode) {
        workingDir projectDir
        environment 'GEODE_HOME', installDir
        environment 'PATH', geodePath
        commandLine 'sh', '-c', "gfsh run --file=${projectDir}/scripts/stop.gfsh"
    }

    task run(type: JavaExec, dependsOn: build) {
        description = 'Run example'
        classpath = sourceSets.main.runtimeClasspath
        main = "org.apache.geode_examples.${project.name}.Example"
    }

    task waitForExitingMembers(type: Exec) {
        workingDir projectDir
        environment 'GEODE_HOME', installDir
        environment 'PATH', geodePath
        ignoreExitValue true
        commandLine 'sh', '-c', "" +
                "TIMEOUT=120 ;" +
                "echo \"Waiting at most \$TIMEOUT seconds for all members to shut down...\" ;" +
                "while pgrep -f \"(Server|Locator)Launcher\" > /dev/null ; do" +
                "  printf \".\" ; " +
                "  sleep 1 ;" +
                "  TIMEOUT=\$((\$TIMEOUT - 1)) ;" +
                "  if [ \$TIMEOUT -eq 0 ] ; then" +
                "    echo \"\" ;" +
                "    exit 10 ;" +
                "  fi ;" +
                "done ;" +
                "echo \"\""
        doLast {
            // We use exit code 10 to avoid conflict with pgrep exit codes.
            if (execResult.exitValue == 10) {
                throw new GradleException("A member process persisted beyond permitted timeout.  Aborting.")
            } else if (execResult.exitValue != 0) {
                throw new GradleException("waitForExistingMembers failed with exit code: " + execResult.exitValue)
            }
        }
    }

    task verifyNoMembersRunning(type: Exec) {
        workingDir projectDir
        environment 'GEODE_HOME', installDir
        environment 'PATH', geodePath
        ignoreExitValue true
        commandLine 'sh', '-c', "echo \"Looking for existing member processes...\" ; " +
                "pgrep -f \"(Server|Locator)Launcher\" ; "
        doLast {
            if (execResult.exitValue == 0) {
                throw new GradleException("Existing members detected.  Examples expect a clean environment in which to run.")
            }
        }
    }
    if (gradle.usingGeodeCompositeBuild) {
        tasks.withType(JavaCompile) {
            options.fork = true
            options.forkOptions.jvmArgs += ['-Xmx3g']
        }
    }

    task runAll(dependsOn: [verifyNoMembersRunning, start, run, stop, waitForExitingMembers])
    start.mustRunAfter verifyNoMembersRunning
    run.mustRunAfter start
    stop.mustRunAfter run
    waitForExitingMembers.mustRunAfter stop
}

apply from: "gradle/spotless.gradle"
apply from: "gradle/ide.gradle"
apply from: "gradle/rat.gradle"
apply from: "gradle/release.gradle"
