package net.taehui.twilight.system

import com.fasterxml.jackson.annotation.JsonGetter
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonSetter
import com.fasterxml.jackson.databind.ObjectMapper
import net.taehui.twilight.Logger
import net.taehui.twilight.TwilightComponent
import java.io.IOException
import java.lang.reflect.Modifier
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit

object Configure : Logger {
    class PathItem {
        @JvmField
        var www = ""

        @JvmField
        var tmp = ""

        @JvmField
        var date = ""

        @JsonIgnore
        lateinit var wwwPath: Path

        @JsonIgnore
        lateinit var tmpPath: Path

        @JsonIgnore
        lateinit var datePath: Path

        @JsonSetter
        fun setWww(www: String) {
            this.www = www
            wwwPath = Paths.get(www)
        }

        @JsonSetter
        fun setTmp(tmp: String) {
            this.tmp = tmp
            tmpPath = Paths.get(tmp)
        }

        @JsonSetter
        fun setDate(date: String) {
            this.date = date
            datePath = Paths.get(date)
        }
    }

    class DBItem {
        var auth = ""
        var db = ""
        var remote = ""
        var avatar = ""
        var format = ""
    }

    class FaxItem {
        var auth = ""
        var remote = ""
        var avatar = ""
    }

    class JavaCipherStore {
        @get:JsonGetter
        lateinit var pw0: CharArray

        @get:JsonGetter
        lateinit var pw1: CharArray

        @JsonSetter
        fun setPw0(pw0: String) {
            this.pw0 = pw0.toCharArray()
        }

        @JsonSetter
        fun setPw1(pw1: String) {
            this.pw1 = pw1.toCharArray()
        }
    }

    class Mode {
        var getAbility = false
        var platform = false
        var tv = false

        @JsonIgnore
        var pause = false
    }

    class Www {
        var qwilight = ""
        var taehui = ""
        var remote = ""
    }

    class NHN {
        var nhnID = ""
        var nhnPw = ""
    }

    lateinit var path: PathItem
    lateinit var db: DBItem
    lateinit var fax: FaxItem
    lateinit var javaCipherStore: JavaCipherStore
    var hash = mutableSetOf<String>()
    lateinit var mode: Mode
    lateinit var www: Www
    lateinit var nhn: NHN
    var awilightCount = 0
    var defaultNoteDate = 0L
    var defaultUIDate = 0L

    fun loadConfigure() {
        try {
            val text = ObjectMapper().readValue(Paths.get("Configure.json").toFile(), Configure::class.java)
            Configure::class.java.fields.forEach {
                if (it.getAnnotation(JsonIgnore::class.java)?.value != true && it.modifiers and Modifier.FINAL != Modifier.FINAL) {
                    it[this] = it[text] ?: throw RuntimeException(it.name)
                }
            }
            defaultNoteDate = Files.getLastModifiedTime(TwilightComponent.DEFAULT_NOTE_ENTRY).to(TimeUnit.MILLISECONDS)
            defaultUIDate = Files.getLastModifiedTime(TwilightComponent.DEFAULT_UI_ENTRY).to(TimeUnit.MILLISECONDS)
            logInfo("Loaded Configure")
        } catch (e: IOException) {
            logFault(e)
        }
    }

    fun saveConfigure() {
        Files.newOutputStream(Paths.get("Configure.json")).use {
            ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(it, this)
            logInfo("Saved Configure")
        }
    }
}