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

def licenseString = """#
# Copyright 2017 the original author or authors.
#
# Licensed 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."""

// 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 licenseWritten = false
            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)
                // Print the licence after the shebang.
                if(!licenseWritten && line.contains("#!/usr/bin/env sh")) {
                    out.println()
                    out.print(licenseString)
                    licenseWritten = true
                }
                out.println() // New Line
            }
        }
    }
}
wrapper.finalizedBy bootstrapWrapper

// Custom task to add a license header to the gradle-wrapper.properties file.
task bootstrapWrapperProperties() {
    // In the doLast block so this runs when the task is called and not during project configuration.
    doLast {
        def wrapperProperties = wrapper.propertiesFile
        def wrapperLines = wrapperProperties.readLines()
        wrapperProperties.withPrintWriter { out ->
            // Print the license
            out.println(licenseString)
            wrapperLines.each { line ->
                out.println(line)
            }
        }
    }
}
wrapper.finalizedBy bootstrapWrapperProperties

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