//
// Copyright (c) 2008-2020 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

import org.gradle.internal.io.NullOutputStream
import java.io.ByteArrayOutputStream

buildscript {
    extra["kotlinVersion"] = "1.4.10"
    val kotlinVersion: String by extra
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:4.0.2")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
    }
}

plugins {
    id("com.jfrog.bintray") version "1.8.5" apply false
}

val kotlinVersion: String by ext

allprojects {
    group = "io.urho3d"
    version = determineVersion()
    description = """
        Urho3D is a free lightweight, cross-platform 2D and 3D game engine implemented in C++ and
        released under the MIT license. Greatly inspired by OGRE and Horde3D.
    """.trimIndent().replace('\n', ' ')
    repositories {
        google()
        jcenter()
    }
    buildscript {
        ext {
            set("kotlinVersion", kotlinVersion)
            set("ndkSideBySideVersion", "21.3.6528147")
            set("cmakeVersion", "3.17.3+")
            set("buildStagingDir", ".cxx")
        }
    }
}

tasks {
    wrapper {
        distributionType = Wrapper.DistributionType.ALL
    }
    "prepareKotlinBuildScriptModel" {
        listOf("Debug", "Release").forEach {
            dependsOn(":android:urho3d-lib:generateJsonModel$it")
        }
    }
    register<Delete>("clean") {
        // Clean the build artifacts generated by the Gradle build system only, but keep the buildDir
        rootProject.buildDir.listFiles { _, name -> name == "intermediates" || name == "kotlin" }?.let {
            delete = it.toSet()
        }
    }
    register<Delete>("cleanAll") {
        dependsOn("clean")
    }
    register("aarVersion") {
        doLast {
            println("AAR version: ${determineVersion()}")
        }
    }
}

/**
 * Find the most recent tag that is reachable from a commit and use that to set the Gradle's project version.
 *
 * e.g. commit described as "1.7-664-g34b1" will be mapped to "1.8-SNAPSHOT", (development snapshot for next version)
 *      tag "1.8" will be mapped to "1.8" as is (point release version), so does tag "1.8-RC" (release candidate)
 */
fun determineVersion(): String {
    // If it is explicitly specified then use the specified version instead
    System.getenv("GRADLE_PROJECT_VERSION")?.let { return it }
    val desc = describeCommit()
    return Regex("^(.+?)-\\d").find(desc)?.destructured?.component1()?.let { "${bumpSemVer(it, 1)}-SNAPSHOT" } ?: desc
}

/**
 * Find the most recent tag that is reachable from a commit.
 */
fun describeCommit(sha: String? = null) = ByteArrayOutputStream().also {
    exec {
        commandLine = listOf("git", "describe", "--tags", sha ?: "--dirty")
        standardOutput = it
        errorOutput = NullOutputStream.INSTANCE
        isIgnoreExitValue = true    // In case no GIT command line tool or not a GIT repository
    }
}.toString().trim().let { if (it.isBlank()) "Unversioned" else it }

/**
 * Bump the semantic versioning on the specified index, 0 for major version, 1 for minor version, and so on.
 */
fun bumpSemVer(version: String, index: Int) = version
    .split('.')
    .mapIndexed { i: Int, s: String ->
        when {
            i < index -> s
            i == index -> if (s.contains('-')) s else (s.toInt() + 1).toString()
            else -> "0"
        }
    }
    .joinToString(".")
