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

// This file contains tasks for the gradle wrapper generation.

// Ensure the wrapper script is generated based on the version defined in the project
// and not the version installed on the machine running the task.
// Read more about the wrapper here: https://docs.gradle.org/current/userguide/gradle_wrapper.html
wrapper {
    gradleVersion = project.gradleVersion
    distributionType = Wrapper.DistributionType.ALL
}

// Custom task to inject support for downloading the gradle wrapper jar if it doesn't exist.
// This allows us to avoid checking in the jar to our repository.
// Additionally adds a license header to the wrapper while editing the file contents.
task bootstrapWrapper() {
    // In the doLast block so this runs when the task is called and not during project configuration.
    doLast {
        def wrapperBasePath = "\$APP_HOME/gradle/wrapper"
        def wrapperJarPath = wrapperBasePath + "/gradle-wrapper.jar"

        // Add a trailing zero to the version if needed.
        def fullVersion = project.gradleVersion.count(".") == 1 ? "${project.gradleVersion}.0" : versions.gradle
        // Leverages the wrapper jar checked into the gradle project on github because the jar isn't
        // available elsewhere. Using raw.githubusercontent.com instead of github.com because
        // github.com servers deprecated TLSv1/TLSv1.1 support some time ago, so older versions
        // of curl (built against OpenSSL library that doesn't support TLSv1.2) would fail to
        // fetch the jar.
        def wrapperBaseUrl = "https://raw.githubusercontent.com/gradle/gradle/v$fullVersion/gradle/wrapper"
        def wrapperJarUrl = wrapperBaseUrl + "/gradle-wrapper.jar"

        def bootstrapString = """
      # Loop in case we encounter an error.
      for attempt in 1 2 3; do
        if [ ! -e $wrapperJarPath ]; then
          if ! curl -s -S --retry 3 -L -o "$wrapperJarPath" "$wrapperJarUrl"; then
            rm -f "$wrapperJarPath"
            # Pause for a bit before looping in case the server throttled us.
            sleep 5
            continue
          fi
        fi
      done
      """.stripIndent()

        def wrapperScript = wrapper.scriptFile
        def wrapperLines = wrapperScript.readLines()
        wrapperScript.withPrintWriter { out ->
            def bootstrapWritten = false
            wrapperLines.each { line ->
                // Print the wrapper bootstrap before the first usage of the wrapper jar.
                if (!bootstrapWritten && line.contains("gradle-wrapper.jar")) {
                    out.println(bootstrapString)
                    bootstrapWritten = true
                }
                out.print(line)
                out.println()
            }
        }
    }
}
wrapper.finalizedBy bootstrapWrapper

// Remove the generated batch file since we don't test building in the Windows environment.
task removeWindowsScript(type: Delete) {
    delete "$rootDir/gradlew.bat"
}
wrapper.finalizedBy removeWindowsScript
