Newer
Older
Twilight / src / main / kotlin / net / taehui / twilight / system / IO.kt
@Taehui Taehui on 6 Nov 21 KB 2023-11-06 오후 7:15
package net.taehui.twilight.system

import net.taehui.twilight.BaseCompiler
import net.taehui.twilight.Logger
import net.taehui.twilight.TwilightComponent
import org.apache.commons.codec.binary.Hex
import org.jline.reader.UserInterruptException
import java.nio.file.Files
import java.nio.file.Path
import java.security.MessageDigest
import java.time.LocalDateTime
import java.util.concurrent.CompletableFuture
import java.util.concurrent.atomic.AtomicInteger
import java.util.stream.StreamSupport


object IO : Logger {
    private val futureNoteLearnerStatus = AtomicInteger()
    private var futureNoteLearner: CompletableFuture<Void>? = null
    private var futureCommentLearner: CompletableFuture<Void>? = null
    private var futureWipeNote = ""
    private var futureWipeNotes: Collection<String>? = null
    private var futureWipeComment = ""
    private var futureWipeComments: Collection<Path>? = null
    private var futureWipeBundles: Collection<Path>? = null

    fun handleSystem(): String {
        var stopText: String? = null
        val r = Window.window.r
        while (stopText == null) {
            try {
                val line = r.readLine("> ")
                if (line.isNotEmpty()) {
                    val w = r.parsedLine.words()
                    if (futureWipeNote.isNotEmpty()) {
                        if ("y".equals(w[0], ignoreCase = true)) {
                            DB.wipeNote(futureWipeNote)
                        } else {
                            logInfo("Cancelled")
                        }
                        futureWipeNote = ""
                        continue
                    }
                    if (futureWipeNotes != null) {
                        if ("y".equals(w[0], ignoreCase = true)) {
                            DB.wipeNotes(futureWipeNotes!!)
                        } else {
                            logInfo("Cancelled")
                        }
                        futureWipeNotes = null
                        continue
                    }
                    if (futureWipeComment.isNotEmpty()) {
                        if ("y".equals(w[0], ignoreCase = true)) {
                            DB.wipeComment(futureWipeComment)
                        } else {
                            logInfo("Cancelled")
                        }
                        futureWipeComment = ""
                        continue
                    }
                    if (futureWipeComments != null) {
                        if ("y".equals(w[0], ignoreCase = true)) {
                            DB.wipeComments(futureWipeComments!!)
                        } else {
                            logInfo("Cancelled")
                        }
                        futureWipeComments = null
                        continue
                    }
                    if (futureWipeBundles != null) {
                        if ("y".equals(w[0], ignoreCase = true)) {
                            DB.wipeBundles(futureWipeBundles!!)
                        } else {
                            logInfo("Cancelled")
                        }
                        futureWipeBundles = null
                        continue
                    }
                    when (w[0]) {
                        "stop" -> stopText = if (w.size > 1) w[1] else ""

                        "alarm" -> {
                            if (w.size > 2) {
                                SiteHandler.setSiteNotify(
                                    SiteHandler.getSiteID(w[1]),
                                    w[2]
                                )
                            } else if (w.size > 1) {
                                AvatarHandler.justNotify(w[1])
                            } else {
                                logInfo("alarm <Site ID> <Text>")
                            }
                        }

                        "avatar" -> {
                            if (w.size > 1) {
                                when (w[1]) {
                                    "view" -> {
                                        AvatarHandler.doInfo(this)
                                        continue
                                    }

                                    "quit" -> {
                                        if (w.size > 2) {
                                            AvatarHandler.handleNotSignIn(w[2])
                                        } else {
                                            logInfo("avatar quit <Avatar ID>")
                                        }
                                        continue
                                    }

                                    "ban" -> {
                                        if (w.size > 3) {
                                            AvatarHandler.getAvatar(
                                                w[2]
                                            ).let {
                                                if (it != null) {
                                                    BannedIP.putBannedIP(
                                                        it.remote, LocalDateTime.parse(
                                                            w[3]
                                                        )
                                                    )
                                                    it.close()
                                                } else {
                                                    logInfo("Failed to Find ID")
                                                }
                                            }
                                        } else {
                                            logInfo("avatar ban <Avatar ID> <Date>")
                                        }
                                        continue
                                    }

                                    "allow" -> {
                                        if (w.size > 2) {
                                            BannedIP.wipeBannedIP(w[2])
                                        } else {
                                            logInfo("avatar allow <Avatar IP>")
                                        }
                                        continue
                                    }
                                }
                            }
                            logInfo("avatar [view] view Avatars")
                            logInfo("avatar [quit] Quit Avatar")
                            logInfo("avatar [ban] Ban Avatar IP")
                            logInfo("avatar [allow] Allow Avatar IP")
                        }

                        "awilight" -> {
                            if (w.size > 2) {
                                if ("set" == w[1]) {
                                    val awilightCount = w[2].toInt()
                                    Configure.awilightCount =
                                        0.coerceAtLeast(Configure.awilightCount + awilightCount)
                                    AwilightHandler.setAwilightCount(
                                        awilightCount
                                    )
                                    continue
                                } else {
                                    logInfo("awilight set <Count>")
                                }
                            }
                            logInfo("awilight [set] Set Awilight")
                        }

                        "bundle" -> {
                            if (w.size > 1) {
                                if ("wipe" == w[1]) {
                                    DB.getWipeBundles().thenAccept {
                                        if (it.isNotEmpty()) {
                                            futureWipeBundles = it
                                        }
                                        logInfo("${it.size} Bundle Files")
                                    }
                                    continue
                                }
                            }
                            logInfo("bundle [wipe] Wipe Bundle Files")
                        }

                        "comment" -> {
                            if (w.size > 1) {
                                when (w[1]) {
                                    "wipe" -> {
                                        if (w.size > 2) {
                                            DB.getWipeComment(w[2]).thenAccept {
                                                if (it > 0) {
                                                    futureWipeComment = w[2]
                                                }
                                                logInfo("$it Comment Files")
                                            }
                                        } else {
                                            DB.getWipeComments().thenAccept {
                                                if (it.isNotEmpty()) {
                                                    futureWipeComments = it
                                                }
                                                logInfo("${it.size} Comment Files")
                                            }
                                        }
                                        continue
                                    }

                                    "learn" -> {
                                        if (w.size > 2) {
                                            if (futureCommentLearner?.isDone != false) {
                                                futureCommentLearner = DB.setCommentMax(w[2])
                                            } else {
                                                logInfo(
                                                    "Learning Comments"
                                                )
                                            }
                                        } else {
                                            logInfo("comment learn <Avatar ID>")
                                        }
                                        continue
                                    }
                                }
                            }
                            logInfo("comment [wipe] <Avatar ID> Wipe Comment Files")
                            logInfo("comment [learn] <Avatar ID> Learn Comments")
                        }

                        "note" -> {
                            if (w.size > 1) {
                                when (w[1]) {
                                    "learn" -> {
                                        fun learnNoteFile(noteFilePath: Path): Boolean {
                                            try {
                                                val noteData = Files.readAllBytes(noteFilePath)
                                                val hashComputer512 = MessageDigest.getInstance("SHA-512")
                                                hashComputer512.update(noteData)
                                                val hashComputer128 = MessageDigest.getInstance("MD5")
                                                hashComputer128.update(noteData)
                                                val hashComputer256 = MessageDigest.getInstance("SHA-256")
                                                hashComputer256.update(noteData)
                                                val noteID512 = Hex.encodeHexString(hashComputer512.digest())
                                                val noteID128 = Hex.encodeHexString(hashComputer128.digest())
                                                val noteID256 = Hex.encodeHexString(hashComputer256.digest())
                                                val targetComputing = BaseCompiler.handleCompile(noteData)
                                                DB.setNote(
                                                    "$noteID512:0",
                                                    noteID128,
                                                    noteID256,
                                                    targetComputing
                                                )
                                                return true
                                            } catch (e: Throwable) {
                                                logFault(e)
                                                return false
                                            }
                                        }

                                        if (w.size > 2) {
                                            learnNoteFile(Path.of(w[2]))
                                        } else {
                                            if (futureNoteLearner?.isDone != false) {
                                                futureNoteLearner = logFuture {
                                                    DB.wipeNotes()
                                                    try {
                                                        Files.newDirectoryStream(
                                                            TwilightComponent.NOTE_ENTRY_PATH
                                                        )
                                                            .use {
                                                                StreamSupport.stream(it.spliterator(), true)
                                                                    .forEach { noteFilePath ->
                                                                        if (learnNoteFile(noteFilePath)) {
                                                                            futureNoteLearnerStatus.incrementAndGet()
                                                                        }
                                                                    }
                                                            }
                                                    } finally {
                                                        logInfo(
                                                            "Learned ${futureNoteLearnerStatus.get()} Note Files"
                                                        )
                                                        futureNoteLearnerStatus.set(0)
                                                    }
                                                }
                                            } else {
                                                logInfo(
                                                    "Learning ${futureNoteLearnerStatus.get()} Note Files"
                                                )
                                            }
                                        }
                                        continue
                                    }

                                    "ban" -> {
                                        if (w.size > 3) {
                                            BannedNote.putBannedIP(w[2], w[3])
                                        } else {
                                            logInfo("note ban <Note ID> <Comment>")
                                        }
                                        continue
                                    }

                                    "allow" -> {
                                        if (w.size > 2) {
                                            BannedNote.wipeBannedNote(w[2])
                                        } else {
                                            logInfo("note allow <Note ID>")
                                        }
                                        continue
                                    }

                                    "wipe" -> {
                                        if (w.size > 2) {
                                            DB.getWipeNote(w[2]).thenAccept {
                                                if (it > 0) {
                                                    futureWipeNote = w[2]
                                                }
                                                logInfo("$it Notes")
                                            }
                                        } else {
                                            DB.getWipeNotes().thenAccept {
                                                if (it.isNotEmpty()) {
                                                    futureWipeNotes = it
                                                }
                                                logInfo("${it.size} Notes")
                                            }
                                        }
                                        continue
                                    }
                                }
                            }
                            logInfo("note [learn] <Path> Learn Notes")
                            logInfo("note [ban] <Note ID> Ban Note")
                            logInfo("note [allow] <Note ID> Allow Note")
                            logInfo("note [wipe] <Note ID> Wipe Note File")
                        }

                        "pause" -> {
                            Configure.mode.pause = !Configure.mode.pause
                            Configure.saveConfigure()
                            if (w.size > 1) {
                                AvatarHandler.pause(w[1])
                            } else {
                                AvatarHandler.pause("")
                            }
                        }

                        "platform" -> {
                            if (w.size > 1) {
                                when (w[1]) {
                                    "avatar" -> {
                                        if (w.size > 3) {
                                            PlatformIDSystem.putPlatformID(w[2], w[3])
                                        } else if (w.size > 2) {
                                            PlatformIDSystem.wipePlatformID(w[2])
                                        } else {
                                            logInfo("platform avatar <Platform ID> <Qwilight ID>")
                                        }
                                        continue
                                    }
                                }
                            }
                            logInfo("platform [avatar] <Platform ID> <Qwilight ID>")
                        }

                        "ram" -> {
                            Runtime.getRuntime().gc()
                            logInfo(
                                "Heap: ${
                                    Runtime.getRuntime().totalMemory() / 1000 / 1000
                                } MB / ${Runtime.getRuntime().maxMemory() / 1000 / 1000} MB"
                            )
                        }

                        "site" -> {
                            if (w.size > 1) {
                                when (w[1]) {
                                    "view" -> {
                                        SiteHandler.doInfo(this)
                                        continue
                                    }

                                    "put" -> {
                                        if (w.size > 2) {
                                            SiteHandler.putSite(w[2])
                                        } else {
                                            logInfo("site put <Name>")
                                        }
                                        continue
                                    }

                                    "wipe" -> {
                                        if (w.size > 2) {
                                            SiteHandler.wipeSite(SiteHandler.getSiteID(w[2]))
                                        } else {
                                            logInfo("site wipe <Site ID>")
                                        }
                                        continue
                                    }

                                    "silent" -> {
                                        if (w.size > 2) {
                                            SiteHandler.silentSite(SiteHandler.getSiteID(w[2]))
                                        } else {
                                            logInfo("site silent <Site ID>")
                                        }
                                        continue
                                    }
                                }
                            }
                            logInfo("site [view] view Sites")
                            logInfo("site [put] Put Site")
                            logInfo("site [wipe] Wipe Site")
                            logInfo("site [silent] Silent Site")
                        }

                        else -> {
                            logInfo("[alarm] Send Notify")
                            logInfo("[avatar] Handle Avatars")
                            logInfo("[awilight] Handle Awilight")
                            logInfo("[bundle] Handle Bundles")
                            logInfo("[comment] Handle Comments")
                            logInfo("[note] Handle Notes")
                            logInfo("[pause] Pause Twilight")
                            logInfo("[platform] Handle Platform")
                            logInfo("[site] Handle Sites")
                            logInfo("[stop] Stop Twilight")
                        }
                    }
                }
            } catch (_: UserInterruptException) {
            } catch (e: Throwable) {
                logFault(e)
            }
        }
        return stopText
    }
}