/*
 * 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 com.github.vlsi.gradle.crlf.CrLfSpec
import com.github.vlsi.gradle.crlf.LineEndings
import com.github.vlsi.gradle.git.FindGitAttributes
import com.github.vlsi.gradle.git.dsl.gitignore
import com.github.vlsi.gradle.license.GatherLicenseTask
import com.github.vlsi.gradle.license.api.SpdxLicense
import com.github.vlsi.gradle.release.Apache2LicenseRenderer
import com.github.vlsi.gradle.release.ArtifactType
import com.github.vlsi.gradle.release.ReleaseExtension
import com.github.vlsi.gradle.release.ReleaseParams
import com.github.vlsi.gradle.release.dsl.dependencyLicenses
import com.github.vlsi.gradle.release.dsl.licensesCopySpec

plugins {
    signing
    id("com.github.vlsi.stage-vote-release")
}

rootProject.configure<ReleaseExtension> {
    voteText.set { it.voteTextGen() }
}

fun ReleaseParams.voteTextGen(): String = """
Hi all,

I have created a build for $componentName $version, release
candidate $rc.

Thanks to everyone who has contributed to this release.

You can read the release notes here:
$previewSiteUri/avatica/docs/history.html

The commit to be voted upon:
https://gitbox.apache.org/repos/asf?p=calcite-avatica.git;a=commit;h=$gitSha

Its hash is $gitSha

Tag:
$sourceCodeTagUrl

The artifacts to be voted on are located here:
$svnStagingUri
(revision $svnStagingRevision)

RAT report:
$previewSiteUri/avatica/rat/rat-report.txt

Site preview is here:
$previewSiteUri/avatica/

JavaDoc API preview is here:
$previewSiteUri/avatica/api

The hashes of the artifacts are as follows:
${artifacts.joinToString(System.lineSeparator()) { it.sha512 + System.lineSeparator() + "*" + it.name }}

A staged Maven repository is available for review at:
$nexusRepositoryUri/org/apache/$tlpUrl/

Release artifacts are signed with the following key:
https://people.apache.org/keys/committer/$committerId.asc
https://www.apache.org/dist/$tlpUrl/KEYS

N.B.
To create the jars and test $componentName: "./gradlew build -Prelease -PskipSigning".

If you do not have a Java environment available, you can run the tests
using docker. To do so, install docker and docker-compose, then run
"docker-compose run test" from the root of the directory.

Please vote on releasing this package as $componentName $version.

The vote is open for the next 72 hours and passes if a majority of at
least three +1 PMC votes are cast.

[ ] +1 Release this package as Apache Calcite $version
[ ]  0 I don't feel strongly about it, but I'm okay with the release
[ ] -1 Do not release this package because...


Here is my vote:

+1 (binding)
""".trimIndent()

val distributionGroup = "distribution"
val baseFolder = "apache-calcite-avatica-${rootProject.version}"

// This task scans the project for gitignore / gitattributes, and that is reused for building
// source/binary artifacts with the appropriate eol/executable file flags
val gitProps by tasks.registering(FindGitAttributes::class) {
    // Scanning for .gitignore and .gitattributes files in a task avoids doing that
    // when distribution build is not required (e.g. code is just compiled)
    root.set(rootDir)
}

val getLicenses by tasks.registering(GatherLicenseTask::class) {
    extraLicenseDir.set(file("$rootDir/src/main/config/licenses"))
    // Parts of the web site generated by Jekyll (http://jekyllrb.com/)
    addDependency(":jekyll:", SpdxLicense.MIT)
    addDependency("font-awesome:font-awesome-code:4.2.0", SpdxLicense.MIT)
    addDependency("font-awesome:font-awesome-font:4.2.0", SpdxLicense.OFL_1_1)
    // git.io/normalize
    addDependency(":normalize:3.0.2", SpdxLicense.MIT)
    // Gridism: A simple, responsive, and handy CSS grid by @cobyism
    // https://github.com/cobyism/gridism
    addDependency(":gridsim:", SpdxLicense.MIT)
    addDependency("cobyism:html5shiv:3.7.2", SpdxLicense.MIT)
    addDependency(":respond:1.4.2", SpdxLicense.MIT)
}

val license by tasks.registering(Apache2LicenseRenderer::class) {
    group = LifecycleBasePlugin.BUILD_GROUP
    description = "Generates LICENSE file for the source distribution"
    artifactType.set(ArtifactType.SOURCE)
    metadata.from(getLicenses)
    failOnIncompatibleLicense.set(false)
}

val licenseFiles = licensesCopySpec(license)

fun CopySpec.excludeLicenseFromSourceRelease() {
    // Source release has "/licenses" folder with licenses for third-party dependencies
    // It is populated by "dependencyLicenses" above,
    // so we ignore the folder when building source releases
    exclude("licenses/**")
    exclude("LICENSE")
}

fun CrLfSpec.sourceLayout() = copySpec {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    gitattributes(gitProps)
    into("$baseFolder-src") {
        // Note: license content is taken from "/build/..", so gitignore should not be used
        // Note: this is a "license + third-party licenses", not just Apache-2.0
        dependencyLicenses(licenseFiles)
        // Include all the source files
        from(rootDir) {
            gitignore(gitProps)
            excludeLicenseFromSourceRelease()
        }
    }
}

for (archive in listOf(Tar::class)) {
    val taskName = "dist${archive.simpleName}"
    val archiveTask = tasks.register(taskName, archive) {
        val eol = LineEndings.LF
        group = distributionGroup
        description = "Creates source distribution with $eol line endings for text files"
        if (this is Tar) {
            compression = Compression.GZIP
            archiveExtension.set("tar.gz")
        }
        // Gradle does not track "filters" as archive/copy task dependencies,
        // So a mere change of a file attribute won't trigger re-execution of a task
        // So we add a custom property to re-execute the task in case attributes change
        inputs.property("gitproperties", gitProps.map { it.props.attrs.toString() })

        // Gradle defaults to the following pattern:
        // [baseName]-[appendix]-[version]-[classifier].[extension]
        archiveBaseName.set("apache-calcite-avatica")
        archiveClassifier.set("src")

        CrLfSpec(eol).run {
            wa1191SetInputs(gitProps)
            with(sourceLayout())
        }
        doLast {
            logger.lifecycle("Source distribution is created: ${archiveFile.get().asFile}")
        }
    }
    releaseArtifacts {
        artifact(archiveTask)
    }
}
