
import com.beust.klaxon.JsonArray
import com.beust.klaxon.JsonObject
import com.beust.klaxon.Parser
import java.io.File
import java.io.Writer
import java.util.*

// Imports from the file at https://pastebin.com/S7uXzv35, or from PyFa's dynamicitemattributes.0.json

private fun Writer.writeLine(line: String) {
    write(line)
    write("\n")
}


@Suppress("UNCHECKED_CAST")
fun importMutaplasmids(inputFile: File, outputFile: File) {
    val jsonData = inputFile.reader().use { Parser.default().parse(it) as JsonObject }
    outputFile.bufferedWriter().use {
        it.write("""
            // This file is generated by ImportMutaplasmids.kt
            
            /**
             * Encapsulates how the mutaplasmid can modify a single attribute.
             */
            data class AttributeMutation(
                val attributeId: Int,
                val min: Double,
                val max: Double,
                val highIsGood: Boolean? = null
            )
            
            
            /**
             * Encapsulates a single mutaplasmid.
             */
            data class Mutaplasmid(
                val id: Int,
                val targetTypeIds: List<Int>,
                val mutations: List<AttributeMutation>
            )
            
            
        """.trimIndent())

        // Need to split the code into several functions because one long function doesn't compile
        var funcCount = 0
        var mutaplasmidCount = 0
        for ((mutaplasmidId, mutaplasmid) in jsonData.entries) {
            if (mutaplasmidCount % 100 == 0) {
                if (funcCount > 0)
                    it.writeLine("}")
                funcCount += 1
                it.writeLine("fun MutableList<Mutaplasmid>.addMutaplasmids$funcCount() {")
            }
            mutaplasmidCount += 1

            mutaplasmid as JsonObject
            val inputOutputMapping = (mutaplasmid["inputOutputMapping"] as JsonArray<JsonObject>)[0]
            val applicableTypes = inputOutputMapping["applicableTypes"] as JsonArray<Int>
            val attributeIDs = mutaplasmid["attributeIDs"] as JsonObject

            it.writeLine("    add(Mutaplasmid(")
            it.writeLine("        id = $mutaplasmidId,")
            it.writeLine("        targetTypeIds = listOf(${applicableTypes.joinToString(", ")}),")
            it.writeLine("        mutations = listOf(")
            for ((attrId, attrModification) in attributeIDs.entries) {
                attrModification as JsonObject
                val min = attrModification["min"] as Double
                val max = attrModification["max"] as Double
                it.writeLine("            AttributeMutation(")
                it.writeLine("                attributeId = $attrId,")
                it.writeLine("                min = ${String.format(Locale.ROOT, "%.4f", min)},")
                it.writeLine("                max = ${String.format(Locale.ROOT, "%.4f", max)},")
                attrModification["highIsGood"]?.let { highIsGood ->
                    it.writeLine("                highIsGood = ${highIsGood == "1"}")
                }
                it.writeLine("            ),")
            }
            it.writeLine("        )")
            it.writeLine("    ))")
        }
        it.writeLine("}")
        it.writeLine("")
        it.writeLine("val Mutaplasmids = buildList {")
        for (i  in 1 .. funcCount) {
            it.writeLine("    addMutaplasmids$i()")
        }
        it.write("}")
    }
}
