package de.storchp.fdroidbuildstatus.adapter.fdroid

import com.google.gson.Gson
import com.google.gson.JsonElement
import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
import java.io.IOException

@Suppress("UNUSED")
class BaseCommandResultTypeAdapter(gson: Gson) : TypeAdapter<RunningResult?>() {
    private val jsonElementAdapter: TypeAdapter<JsonElement> =
        gson.getAdapter(JsonElement::class.java)
    private val buildCommandResultAdapter: TypeAdapter<BuildResult> =
        gson.getAdapter(BuildResult::class.java)
    private val updateCommandResultTypeAdapter: TypeAdapter<UpdateResult> =
        gson.getAdapter(UpdateResult::class.java)
    private val unknownCommandResultTypeAdapter: TypeAdapter<UnknownResult> =
        gson.getAdapter(UnknownResult::class.java)

    override fun write(out: JsonWriter, value: RunningResult?) {
        throw IllegalStateException("Not implemented")
    }

    @Throws(IOException::class)
    override fun read(`in`: JsonReader): RunningResult? {
        val jsonElement = jsonElementAdapter.read(`in`)
        val subcommand = jsonElement.asJsonObject["subcommand"].asString
        if ("update" == subcommand) {
            return updateCommandResultTypeAdapter.fromJsonTree(jsonElement)
        } else if ("build" == subcommand) {
            return buildCommandResultAdapter.fromJsonTree(jsonElement)
        }
        return unknownCommandResultTypeAdapter.fromJsonTree(jsonElement)
    }

    internal class BaseCommandResultTypeAdapterFactory : TypeAdapterFactory {
        override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
            val rawType: Class<*> = type.rawType
            @Suppress("UNCHECKED_CAST")
            return if (rawType != RunningResult::class.java) {
                null
            } else BaseCommandResultTypeAdapter(gson) as TypeAdapter<T>
        }
    }
}