
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.zip.ZipOutputStream
import org.gradle.language.assembler.tasks.Assemble

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
    }
}

apply { plugin("com.github.johnrengelman.shadow") }

val mainCfg = configurations.create("default")
val relocatedCfg = configurations.create("relocated")

val protobufVersion = rootProject.extra["versions.protobuf-java"]
val protobufJarPrefix = "protobuf-$protobufVersion"
val renamedOutputJarPath = "$buildDir/jars/$protobufJarPrefix-relocated.jar"
val outputJarPath = "$buildDir/libs/$protobufJarPrefix-lite.jar"

artifacts.add(mainCfg.name, File(outputJarPath))
artifacts.add(relocatedCfg.name, File(renamedOutputJarPath))

dependencies {
    mainCfg("com.google.protobuf:protobuf-java:$protobufVersion")
}

val relocateTask = task<ShadowJar>("prepare-relocated-protobuf") {
    archiveName = renamedOutputJarPath
    this.configurations = listOf(relocatedCfg)
    from(mainCfg.files.find { it.name.startsWith("protobuf-java") }?.canonicalPath)
    relocate("com.google.protobuf", "org.jetbrains.kotlin.protobuf" ) {
        // TODO: remove "it." after #KT-12848 get addressed
        exclude("META-INF/maven/com.google.protobuf/protobuf-java/pom.properties")
    }
}

val mainTask = task("prepare") {
    dependsOn(relocateTask)
    val inputJar = renamedOutputJarPath
    inputs.files(inputJar)
    outputs.file(outputJarPath)
    doFirst {
        File(outputJarPath).parentFile.mkdirs()
    }
    doLast {
        val INCLUDE_START = "<include>**/"
        val INCLUDE_END = ".java</include>"
        val POM_PATH = "META-INF/maven/com.google.protobuf/protobuf-java/pom.xml"

        fun loadAllFromJar(file: File): Map<String, Pair<JarEntry, ByteArray>> {
            val result = hashMapOf<String, Pair<JarEntry, ByteArray>>()
            val jar = JarFile(file)
            try {
                for (jarEntry in jar.entries()) {
                    result[jarEntry.name] = Pair(jarEntry, jar.getInputStream(jarEntry).readBytes())
                }
            }
            finally {
                // Yes, JarFile does not extend Closeable on JDK 6 so we can't use "use" here
                jar.close()
            }
            return result
        }

        val allFiles = loadAllFromJar(File(inputJar))

        val keepClasses = arrayListOf<String>()

        val pomBytes = allFiles[POM_PATH]?.second ?: error("pom.xml is not found in protobuf jar at $POM_PATH")
        val lines = String(pomBytes).lines()

        var liteProfileReached = false
        for (lineUntrimmed in lines) {
            val line = lineUntrimmed.trim()

            if (liteProfileReached && line == "</includes>") {
                break
            }
            else if (line == "<id>lite</id>") {
                liteProfileReached = true
                continue
            }

            if (liteProfileReached && line.startsWith(INCLUDE_START) && line.endsWith(INCLUDE_END)) {
                keepClasses.add(line.removeSurrounding(INCLUDE_START, INCLUDE_END))
            }
        }

        assert(liteProfileReached && keepClasses.isNotEmpty()) { "Wrong pom.xml or the format has changed, check its contents at $POM_PATH" }

        val outputFile = File(outputJarPath).apply { delete() }
        ZipOutputStream(BufferedOutputStream(FileOutputStream(outputFile))).use { output ->
            for ((name, value) in allFiles) {
                val className = name.substringAfter("org/jetbrains/kotlin/protobuf/").substringBeforeLast(".class")
                if (keepClasses.any { className == it || className.startsWith(it + "$") }) {
                    val (entry, bytes) = value
                    output.putNextEntry(entry)
                    output.write(bytes)
                    output.closeEntry()
                }
            }
        }
    }
}

defaultTasks(mainTask.name)

tasks.withType<Assemble>() {
    dependsOn(mainCfg)
}
