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

To create the jars and test $componentName: "gradle build -Prelease -PskipSign".

If you do not have a Java/Gradle 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 Avatica $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)
    // 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 CopySpec.excludeGradleWrapperFromSourceRelease() {
    // Source distributions must not include binary files (see LEGAL-288).
    // The Gradle wrapper requires gradle-wrapper.jar, so exclude the whole
    // wrapper. Users must install Gradle manually.
    exclude("gradlew")
    exclude("gradlew.bat")
    exclude("gradle/wrapper/**")
}

fun CopySpec.excludeCategoryBLicensedWorksFromSourceRelease() {
    // The source distribution contains "font-awesome:fonts" which is licensed as
    // http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License).
    //
    // OFL 1.1 is "category B" (see LEGAL-112).
    //
    // According to
    // https://www.apache.org/legal/resolved.html#binary-only-inclusion-condition,
    // the source code can not include Category B licensed works.

    // We need to remove "web and desktop font files".
    exclude("site/fonts/**")
}

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()
            excludeGradleWrapperFromSourceRelease()
            excludeCategoryBLicensedWorksFromSourceRelease()
        }
    }
}

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)
    }
}
