package net.taehui.twilight.system import net.taehui.twilight.Logger import org.jline.reader.EndOfFileException import org.jline.reader.UserInterruptException import java.nio.file.Path import java.time.LocalDateTime import java.util.concurrent.CompletableFuture import java.util.concurrent.Future import java.util.concurrent.atomic.AtomicInteger object IO : Logger { private val futureLearnNotesStatus = AtomicInteger() private val futureLearnAvatarsStatus = AtomicInteger() private var futureLearnAvatars: CompletableFuture<Void>? = null private var futureLearnNotes: CompletableFuture<Void>? = null private val futureLearnCommentsStatus = AtomicInteger() private var futureLearnComments: CompletableFuture<Void>? = null private val futureLearnHandledStatus = AtomicInteger() private var futureLearnHandled: CompletableFuture<Void>? = null private var futureWipeNotes: Collection<String>? = null private var futurePMSNotes: Collection<String>? = null 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() val w0 = w[0] if (w0 != "future") { val isY = w0 == "y" if (futureWipeNotes != null) { if (isY) { futureWipeNotes?.forEach { DB.wipeNote(it, this) } } else { logInfo("Cancelled") } futureWipeNotes = null continue } if (futurePMSNotes != null) { if (isY) { futurePMSNotes?.forEach { DB.pmsNote(it, this) } } else { logInfo("Cancelled") } futurePMSNotes = null continue } if (futureWipeComments != null) { if (isY) { DB.wipeComments(futureWipeComments!!).thenAccept { logInfo("Wiped $it Comment Files") } } else { logInfo("Cancelled") } futureWipeComments = null continue } if (futureWipeBundles != null) { if (isY) { DB.wipeBundles(futureWipeBundles!!).thenAccept { logInfo("Wiped $it Bundle Files") } } else { logInfo("Cancelled") } futureWipeBundles = null continue } } when (w0) { "stop" -> stopText = w.elementAtOrNull(1) ?: "" "avatar" -> { if (w.size > 1) { when (w[1]) { "learn" -> { if (futureLearnAvatars?.isDone != false) { futureLearnAvatarsStatus.set(0) futureLearnAvatars = DB.learnAvatars(futureLearnAvatarsStatus).thenRun { logInfo( "Learned ${futureLearnAvatarsStatus.get()} Avatars" ) } } else { logInfo( "Learning ${futureLearnAvatarsStatus.get()} Avatars" ) } continue } "view" -> { AvatarHandler.logInfo(this) continue } "exile" -> { if (w.size > 2) { AvatarHandler.handleNotLogIn(w[2]) continue } } "ban" -> { if (w.size > 3) { AvatarHandler.getAvatar( w[2] ).let { if (it != null) { BannedIPSystem.putBannedIP( it.remote, LocalDateTime.parse( w[3] ) ) it.close() } else { logInfo("Failed to Find ID") } } continue } } "allow" -> { if (w.size > 2) { BannedIPSystem.wipeBannedIP(w[2]) continue } } } } logInfo("avatar learn: Learn Avatars") logInfo("avatar view: View Avatars") logInfo("avatar exile <Avatar ID>: Exile Avatar") logInfo("avatar ban <Avatar ID> <Date>: Ban Avatar IP") logInfo("avatar allow <Avatar IP>: Allow Avatar IP") } "awilight" -> { if (w.size > 1) { when (w[1]) { "set" -> { if (w.size > 2) { val awilightCount = w[2].toInt() Configure.awilightCount = 0.coerceAtLeast(Configure.awilightCount + awilightCount) AwilightHandler.setAwilightCount( awilightCount ) continue } } } } logInfo("awilight set <Count>: Set Awilight") } "bundle" -> { if (w.size > 1) { when (w[1]) { "wipe" -> { DB.getWipeBundles().thenAccept { if (it.isNotEmpty()) { futureWipeBundles = it } logInfo("${it.size} Bundle Files") } continue } } } logInfo("bundle wipe: Clean Bundle Files") } "comment" -> { if (w.size > 1) { when (w[1]) { "learn" -> { if (w.size > 2) { DB.setCommentMax(w[2]) } else { if (futureLearnComments?.isDone != false) { futureLearnCommentsStatus.set(0) futureLearnComments = DB.learnComments(futureLearnCommentsStatus).thenRun { logInfo( "Learned ${futureLearnCommentsStatus.get()} Comments" ) } } else { logInfo( "Learning ${futureLearnCommentsStatus.get()} Comments" ) } } continue } "wipe" -> { DB.getWipeComments().thenAccept { if (it.isNotEmpty()) { futureWipeComments = it } logInfo("${it.size} Comment Files") } continue } } } logInfo("comment learn <Note_ID>: Learn Comments") logInfo("comment wipe: Clean Comment Files") } "future" -> { fun getFutureText(futureStatus: AtomicInteger, future: CompletableFuture<Void>?): String { return if (future != null) { val futureState = future.state() if (futureState == Future.State.FAILED) { "$futureState (${future.exceptionNow()})" } else { "$futureState ($futureStatus)" } } else { Future.State.CANCELLED.toString() } } logInfo("Learning Avatars: ${getFutureText(futureLearnAvatarsStatus, futureLearnAvatars)}") logInfo("Learning Notes: ${getFutureText(futureLearnNotesStatus, futureLearnNotes)}") logInfo( "Learning Comments: ${ getFutureText( futureLearnCommentsStatus, futureLearnComments ) }" ) logInfo( "Learning Handled: ${ getFutureText( futureLearnHandledStatus, futureLearnHandled ) }" ) logInfo("Pending Wipe Notes: ${futureWipeNotes?.size ?: 0}") logInfo("Pending PMS Notes: ${futurePMSNotes?.size ?: 0}") logInfo("Pending Wipe Comments: ${futureWipeComments?.size ?: 0}") logInfo("Pending Wipe Bundles: ${futureWipeBundles?.size ?: 0}") } "handled" -> { if (w.size > 1) { when (w[1]) { "learn" -> { if (futureLearnHandled?.isDone != false) { futureLearnHandledStatus.set(0) futureLearnHandled = DB.learnHandled(futureLearnHandledStatus).thenRun { logInfo( "Learned ${futureLearnHandledStatus.get()} Handled" ) } } else { logInfo( "Learning ${futureLearnHandledStatus.get()} Handled" ) } continue } } } logInfo("handled learn: Learn Handled") } "note" -> { if (w.size > 1) { when (w[1]) { "learn" -> { if (futureLearnNotes?.isDone != false) { futureLearnNotesStatus.set(0) futureLearnNotes = DB.learnNotes(futureLearnNotesStatus).thenRun { logInfo( "Learned ${futureLearnNotesStatus.get()} Notes" ) NoteFilesSystem.loadNoteFiles() } } else { logInfo( "Learning ${futureLearnNotesStatus.get()} Notes" ) } continue } "wipe" -> { if (w.size > 2) { DB.wipeNote(w[2], this) } else { DB.getWipeNotes().thenAccept { if (it.isNotEmpty()) { futureWipeNotes = it } logInfo("${it.size} Notes") } } continue } "pms" -> { if (w.size > 2) { DB.pmsNote(w[2], this) } else { DB.getPMSNotes().thenAccept { if (it.isNotEmpty()) { futurePMSNotes = it } logInfo("${it.size} Notes") } } continue } "ban" -> { if (w.size > 3) { val noteID = w[2] BannedNoteSystem.putBannedNoteFile(noteID, w[3]) DB.wipeNote(noteID, this) continue } } "allow" -> { if (w.size > 2) { BannedNoteSystem.wipeBannedNoteFile(w[2]) continue } } } } logInfo("note learn: Learn Notes") logInfo("note wipe <Note ID>: Clean or Wipe Note File") logInfo("note pms <Note ID>: PMS Note File") logInfo("note ban <Note ID> <Commentary>: Ban Note") logInfo("note allow <Note ID>: Allow Note") } "pause" -> { Configure.mode.pause = !Configure.mode.pause 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]) continue } } "view" -> { logInfo(PlatformSystem.platformStatus) continue } "handle" -> { PlatformSystem.handleSystem() continue } "dispose" -> { PlatformSystem.dispose() continue } } } logInfo("platform avatar <Platform ID> <Qwilight ID>: Put Avatar") logInfo("platform view: View Platform") logInfo("platform handle: Handle Platform") logInfo("platform dispose: Close Platform") } "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.logInfo(this) continue } "put" -> { if (w.size > 2) { SiteHandler.putSite(w[2]) continue } } "wipe" -> { if (w.size > 2) { SiteHandler.wipeSite(SiteHandler.getSiteID(w[2])) continue } } "silent" -> { if (w.size > 2) { SiteHandler.silentSite(SiteHandler.getSiteID(w[2])) continue } } "alarm" -> { if (w.size > 3) { SiteHandler.setSiteNotify( SiteHandler.getSiteID(w[2]), w[3] ) continue } } } } logInfo("site view: View Sites") logInfo("site put <Name>: Put Site") logInfo("site wipe <Site ID>: Wipe Site") logInfo("site silent: Silent Site") logInfo("site alarm <Site ID> <Text>: Send Notify") } "tv" -> { if (w.size > 1) { when (w[1]) { "view" -> { logInfo(TVSystem.tvStatus) continue } "handle" -> { TVSystem.handleSystem() continue } "dispose" -> { TVSystem.dispose() continue } "allow" -> { if (w.size > 2) { TVSystem.putAllowedTV(w[2]) continue } } "ban" -> { if (w.size > 2) { TVSystem.wipeAllowedTV(w[2]) continue } } } } logInfo("tv view: View TV") logInfo("tv handle: Handle TV") logInfo("tv dispose: Close TV") logInfo("tv allow <TV>: Allow TV") logInfo("tv ban <TV>: Ban TV") } "reload" -> { if (w.size > 1) { when (w[1]) { "ability" -> { AbilitySystem.load(true) continue } } } Configure.loadDate() Configure.loadDefaultDate() AvatarIPSystem.loadAvatarIP() BannedNoteSystem.loadBannedNote() BannedIPSystem.loadBannedIP() PlatformIDSystem.loadPlatformID() TVSystem.loadAllowedTV() AbilityClassSystem.loadAbilityClass() AbilitySystem.load(false) EdgeSystem.loadEdge() LevelSystem.loadLevel() TitleSystem.loadTitle() VoteSystem.loadVote() continue } else -> { logInfo("avatar: Handle Avatars") logInfo("awilight: Handle Awilights") logInfo("bundle: Handle Bundles") logInfo("comment: Handle Comments") logInfo("future: View Futures") logInfo("note: Handle Notes") logInfo("pause: Pause Twilight") logInfo("platform: Handle Platform") logInfo("site: Handle Sites") logInfo("tv: Handle TV") logInfo("stop: Stop Twilight") } } } } catch (_: UserInterruptException) { } catch (_: EndOfFileException) { } catch (e: Exception) { logFault(e) } } return stopText } }