package app.revanced.utils import app.revanced.cli.command.MainCommand.logger import app.revanced.patcher.Patcher import app.revanced.patcher.data.Data import app.revanced.patcher.extensions.PatchExtensions.options import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.patch.Patch import cc.ekblad.toml.encodeToString import cc.ekblad.toml.model.TomlValue import cc.ekblad.toml.serialization.from import cc.ekblad.toml.tomlMapper import java.io.File private typealias PatchList = List>> private typealias OptionsMap = MutableMap> object OptionsLoader { @JvmStatic private val mapper = tomlMapper {} @JvmStatic fun init(file: File, patches: PatchList) { if (!file.exists()) file.createNewFile() val map = mapper.decodeWithDefaults(generateDefaults(patches), TomlValue.from(file.toPath())) readAndSet(map, patches) save(map, file) } private fun readAndSet(map: OptionsMap, patches: PatchList) { for ((patchName, options) in map) { val patch = patches.find { it.patchName == patchName } ?: continue val patchOptions = patch.options ?: continue for ((key, value) in options) { if (value == "null") { // backwards compatibility, subject to removal options.remove(key) continue } try { patchOptions[key] = value } catch (e: Exception) { logger.error("Error while setting option $key for patch $patchName: ${e.message}") e.printStackTrace() } } } } private fun save(map: OptionsMap, file: File) { val toml = mapper.encodeToString(map) file.writeText( """ # A list of options for each patch. # This file does not contain all options by default. # Run the CLI with the "--list --with-options" flags to see all available options. # You can also run the CLI with the aforementioned flags and a patch name to see all available options for that patch. # To set an option, add a line with the format "option = value" or set the value if the option already exists. # To reset an option to its default value, delete the line. # To reset all options to their default values, delete this file. # # This file was generated by ReVanced Patcher version ${Patcher.version}. """.trimIndent() + "\n\n$toml" ) } private fun generateDefaults(patches: PatchList) = buildMap { for (patch in patches) { val options = patch.options ?: continue if (!options.iterator().hasNext()) continue put(patch.patchName, buildMap { for (option in options) { put(option.key, option.value ?: continue) } } as MutableMap) } } as MutableMap }