/*
 * 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'
            delete 'redisServer1'
            delete 'redisServer2'
        }
    }
    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"
