package xyz.maxwellj.chookchat

import io.javalin.Javalin
import io.javalin.websocket.WsContext
import io.javalin.http.UploadedFile

import java.util.concurrent.ConcurrentHashMap
import java.util.UUID

import kotlin.concurrent.fixedRateTimer

import org.json.JSONObject
import org.json.JSONArray
import org.json.JSONException

import java.io.File
import java.io.BufferedReader

import java.math.BigInteger
import java.security.MessageDigest

import java.nio.file.Paths
import java.nio.file.Files

fun md5(input:String): String {
    val md = MessageDigest.getInstance("MD5")
    return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0')
}

fun log(input: String) {
    val logFile = File("chookchat.log")
    try {
        logFile.appendText(input)
    } catch (e: Exception) {
        println("Something went wrong with logging to chookchat.log. Here's the error: " + e.toString())
        println("And here's what actually went wrong: " + input)
    }
}

object config {
    var address = ""
    var port = ""
    var security = "" 
    var serviceName = ""

    fun getConfig() {
        address = ""
        port = ""
        security = ""
        serviceName = ""
        val configFile = File("chookchat.config")
        try {
            val config = configFile.readLines()
            var type = ""
            var isEditing = 0
            for (line in config) {
                for (char in line) {
                    if (char == ':') {
                        isEditing = 1
                    } else if (char == ';') {
                        isEditing = 0
                        type = ""
                    } else {
                        if (isEditing == 0) {
                            type += char
                        } else if (isEditing == 1)
                            if (type == "address") {
                                address += char
                            } else if (type == "port") {
                                port += char
                            } else if (type == "security") {
                                security += char
                            } else if (type == "serviceName") {
                                serviceName += char
                            }
                        }
                    }
                }
        } catch (e: Exception) {
            log("Something went wrong :/ Here's the error: $e")
        }
    }
}

object WsSessionManager {
    val peopleOnline = mutableListOf<String>()
    val sessionsList = mutableListOf<String>()
    val sessions = ConcurrentHashMap<WsContext, String>()
    val sessionIds = ConcurrentHashMap<String, WsContext>()
    val userSessions = ConcurrentHashMap<String, String>()
    
    val roomList = mutableListOf<String>()
    val userRooms = ConcurrentHashMap<String, String>() 
    val roomUsers = ConcurrentHashMap<String, MutableList<String>>() 
    
    init {
        createRoom("general")
        
        fixedRateTimer("websocket-ping", period = 5000) {
            sendPing()
        }
    }
    
    fun createRoom(roomName: String): Boolean {
        if (roomList.contains(roomName)) {
            return false
        }
        roomList.add(roomName)
        roomUsers[roomName] = mutableListOf()
        return true
    }
    
    fun joinRoom(username: String, roomName: String): Boolean {
        if (!roomList.contains(roomName)) {
            createRoom(roomName)
        }
        
        val currentRoom = userRooms[username]
        if (currentRoom != null) {
            roomUsers[currentRoom]?.remove(username)
            
            val leftMessage = JSONObject().apply {
                put("type", "roomLeave")
                put("username", "system")
                put("room", currentRoom)
                put("content", "$username left the room")
            }
            broadcastToRoom(currentRoom, leftMessage.toString())
            
            broadcastRoomUsers(currentRoom)
        }
        
        userRooms[username] = roomName
        roomUsers[roomName]?.add(username)
        
        broadcastRoomUsers(roomName)
        return true
    }
    
    fun getRoomUsers(roomName: String): List<String> {
        return roomUsers[roomName] ?: listOf()
    }
    
    fun broadcastRoomUsers(roomName: String) {
        val usersInRoom = roomUsers[roomName] ?: listOf()
        val processedData = JSONObject().apply {
            put("type", "roomUsers")
            put("username", "system")
            put("room", roomName)
            put("content", usersInRoom.joinToString(", "))
        }
        broadcastToRoom(roomName, processedData.toString(), false)
    }
    
    fun broadcastOnlineUsers() {
        val processedData = JSONObject().apply {
            put("type", "users")
            put("username", "system")
            put("content", peopleOnline.joinToString(", "))
        }
        broadcast(processedData.toString())
    }
    
    fun broadcastToRoom(roomName: String, message: String, cleanupDeadSessions: Boolean = true) {
        val deadSessions = mutableListOf<WsContext>()
        
        sessions.keys.forEach { ctx ->
            try {
                if (ctx.session.isOpen) {
                    val sessionId = sessions[ctx]
                    if (sessionId != null) {
                        val username = userSessions.entries.find { it.value == sessionId }?.key
                        if (username != null && userRooms[username] == roomName) {
                            ctx.send(message)
                        }
                    }
                } else {
                    deadSessions.add(ctx)
                }
            } catch (e: Exception) {
                log("Error broadcasting to session: ${e.message}")
                deadSessions.add(ctx)
            }
        }
        
        if (cleanupDeadSessions) {
            deadSessions.forEach { removeSessionWithoutBroadcast(it) }
        }
    }
    
    private fun removeSessionWithoutBroadcast(ctx: WsContext) {
        try {
            val sessionId = sessions[ctx]
            if (sessionId != null) {
                userSessions.entries.find { it.value == sessionId }?.let { entry ->
                    val username = entry.key
                    val room = userRooms[username]
                    
                    if (room != null) {
                        roomUsers[room]?.remove(username)
                    }
                    
                    peopleOnline.remove(username)
                    userSessions.remove(username)
                    userRooms.remove(username)
                }

                sessionsList.remove(sessionId)
                sessions.remove(ctx)
                sessionIds.remove(sessionId)
            }
        } catch (e: Exception) {
            log("Error removing session without broadcast: ${e.message}")
        }
    }
    
    fun handleUserLogin(username: String) {
        if (!peopleOnline.contains(username)) {
            peopleOnline.add(username)
            if (!userRooms.containsKey(username)) {
                joinRoom(username, "general")
            }
            broadcastOnlineUsers()
        }
    }
    
    private fun sendPing() {
        val deadSessions = mutableListOf<WsContext>()

        sessions.keys.forEach { ctx ->
            try {
                if (ctx.session.isOpen) {
                    ctx.send("ping")
                } else {
                    deadSessions.add(ctx)
                }
            } catch (e: Exception) {
                log("Error sending ping: ${e.message}")
                deadSessions.add(ctx)
            }
        }
        deadSessions.forEach { removeSession(it) }
    }
    
    fun addSession(ctx: WsContext) {
        try {
            val sessionId = UUID.randomUUID().toString()
            sessionsList.add(sessionId)  
            sessions[ctx] = sessionId
            sessionIds[sessionId] = ctx
        } catch (e: Exception) {
            log("Error adding session: ${e.message}")
        }
    }

    fun removeSession(ctx: WsContext) {
        try {
            val sessionId = sessions[ctx]
            if (sessionId != null) {
                userSessions.entries.find { it.value == sessionId }?.let { entry ->
                    val username = entry.key
                    val room = userRooms[username]
                    
                    if (room != null) {
                        roomUsers[room]?.remove(username)
                        broadcastRoomUsers(room)
                    }
                    
                    peopleOnline.remove(username)
                    userSessions.remove(username)
                    userRooms.remove(username)
                }

                sessionsList.remove(sessionId)
                sessions.remove(ctx)
                sessionIds.remove(sessionId)
                broadcastOnlineUsers()
            }
        } catch (e: Exception) {
            log("Error removing session: ${e.message}")
        }
    }

    fun associateUserWithSession(username: String, ctx: WsContext) {
        val sessionId = sessions[ctx]
        if (sessionId != null) {
            userSessions[username] = sessionId
        }
    }
    
    fun broadcast(message: String) {
        val deadSessions = mutableListOf<WsContext>()
        
        sessions.keys.forEach { ctx ->
            try {
                if (ctx.session.isOpen) {
                    ctx.send(message)
                } else {
                    deadSessions.add(ctx)
                }
            } catch (e: Exception) {
                log("Error broadcasting to session: ${e.message}")
                deadSessions.add(ctx)
            }
        }
        
        deadSessions.forEach { removeSession(it) }
    }

    fun getSessionCount(): Int = sessions.size
    
    fun getUserRoom(username: String): String? {
        return userRooms[username]
    }
    
    fun getRooms(): List<String> {
        return roomList
    }
}

fun extractMessageContent(inputData: String, ctx: WsContext): String {
    val jsonInputData = JSONObject(inputData)
    
    if (jsonInputData.getString("type") == "connect") {
        val username = jsonInputData.getString("username")
        WsSessionManager.associateUserWithSession(username, ctx)
        WsSessionManager.handleUserLogin(username)
        
        val processedData = JSONObject().apply {
            put("type", "connect")
            put("username", "system")
            put("content", "${jsonInputData.getString("username")} just joined the chat!")
        }
        return processedData.toString()
    }
    
    if (jsonInputData.getString("type") == "joinRoom") {
        val username = jsonInputData.getString("username")
        val roomName = jsonInputData.getString("room")
        
        if (!jsonInputData.has("token")) {
            val processedData = JSONObject().apply {
                put("type", "error")
                put("username", "system")
                put("content", "Authentication required")
            }
            return processedData.toString()
        }
        
        val success = WsSessionManager.joinRoom(username, roomName)
        if (success) {
            val processedData = JSONObject().apply {
                put("type", "roomJoin")
                put("username", "system")
                put("room", roomName)
                put("content", "$username just joined the room!")
            }
            return processedData.toString()
        } else {
            val processedData = JSONObject().apply {
                put("type", "error")
                put("username", "system")
                put("content", "Failed to join room: $roomName")
            }
            return processedData.toString()
        }
    }
    
    if (jsonInputData.getString("type") == "getUsersInRoom") {
        val username = jsonInputData.getString("username")
        val roomName = jsonInputData.getString("room")
        
        if (!jsonInputData.has("token")) {
            val processedData = JSONObject().apply {
                put("type", "error")
                put("username", "system")
                put("content", "Authentication required")
            }
            return processedData.toString()
        }
        
        val usersInRoom = WsSessionManager.getRoomUsers(roomName)
        val processedData = JSONObject().apply {
            put("type", "roomUsers")
            put("username", "system")
            put("room", roomName)
            put("content", usersInRoom.joinToString(", "))
        }
        return processedData.toString()
    }
    
    if (jsonInputData.getString("type") == "createRoom") {
        val username = jsonInputData.getString("username")
        val roomName = jsonInputData.getString("room")
        
        if (!jsonInputData.has("token")) {
            val processedData = JSONObject().apply {
                put("type", "error")
                put("username", "system")
                put("content", "Authentication required")
            }
            return processedData.toString()
        }
        
        val success = WsSessionManager.createRoom(roomName)
        if (success) {
            WsSessionManager.joinRoom(username, roomName)
            val processedData = JSONObject().apply {
                put("type", "roomCreated")
                put("username", "system")
                put("room", roomName)
                put("content", "Room '$roomName' created and joined!")
            }
            return processedData.toString()
        } else {
            val processedData = JSONObject().apply {
                put("type", "error")
                put("username", "system") 
                put("content", "Room '$roomName' already exists!")
            }
            return processedData.toString()
        }
    }
    
    val username = jsonInputData.getString("username")
    val room = WsSessionManager.getUserRoom(username) ?: "general"
    
    val processedData = JSONObject().apply {
        put("type", jsonInputData.getString("type"))
        put("username", username)
        put("room", room)
        put("content", jsonInputData.getString("content"))
    }
    
    return processedData.toString()
}

fun handleSentMessage(inputData: String): String {
    log("API request received: $inputData")
    var jsonInputData: JSONObject
    try {
        jsonInputData = JSONObject(inputData)
    } catch (error: JSONException) {
        return error.toString()
    }
    
    val username = jsonInputData.getString("username")
    val token = jsonInputData.getString("token")
    val content = jsonInputData.getString("content")
    val type = jsonInputData.getString("type")
    
    if (jsonInputData.has("type")) {
        val type = jsonInputData.getString("type")
        if (type == "joinRoom" || type == "createRoom") {
            val userDatabaseParser = BufferedReader(File("userDatabase").reader())
            var userLine = ""
            
            userDatabaseParser.forEachLine { line ->
                if (line.contains(username)) {
                    userLine = line
                }
            }
            userDatabaseParser.close()
            
            if (userLine == "") {
                val processedData = JSONObject().apply {
                    put("type", "error")
                    put("username", "system")
                    put("content", "unknown-account")
                }    
                return processedData.toString()
            }
            
            var tokenInDatabase = ""
            var currentStage = 0
            for (char in userLine) {
                if (char == ':') {
                    currentStage++
                }
                if (currentStage == 1) {
                    tokenInDatabase += char
                }
            }
            tokenInDatabase = tokenInDatabase.replace(":", "")
            
            if (token != tokenInDatabase) {
                val processedData = JSONObject().apply {
                    put("type", "error")
                    put("username", "system")
                    put("content", "invalid-token")
                }
                return processedData.toString()
            }
            
            return "Success" 
        }
    }
    
    val userDatabaseParser = BufferedReader(File("userDatabase").reader())
    var lineNumber = 1
    var userLine = ""
    
    userDatabaseParser.forEachLine { line ->
        if (line.contains(username)) {
            userLine = line
        }
        lineNumber++
    }
    userDatabaseParser.close()

    if (userLine == "") {
        val processedData = JSONObject().apply {
            put("type", "error")
            put("username", "system")
            put("content", "unknown-account")
        }    
        return processedData.toString()
    }
 
    var usernameInDatabase = ""
    var tokenInDatabase = ""
    var saltInDatabase = ""
    var banStatus = ""
    var currentStage = 0
    for (char in userLine) {
        if (char == ':') {
            currentStage ++
        }
        if (currentStage == 0) {
            usernameInDatabase += char
        } else if (currentStage == 1) {
            tokenInDatabase += char
        } else if (currentStage == 2) {
            saltInDatabase += char
        } else if (currentStage == 3) {
            banStatus += char
        }
    }
    tokenInDatabase = tokenInDatabase.replace(":", "")
    saltInDatabase = saltInDatabase.replace(":", "")
    banStatus = banStatus.replace(":", "")
    
    if (banStatus == "1") {
        val processedData = JSONObject().apply {
            put("type", "error")
            put("username", "system")
            put("content", "banned")
        }    
        return processedData.toString()
    }
    
    if (token != tokenInDatabase) {
        val processedData = JSONObject().apply {
            put("type", "error")
            put("username", "system")
            put("content", "invalid-token")
        }
        return processedData.toString()
    }
    
    if (content != "") {
        if (type == "typing") return "Success"
        val room = WsSessionManager.getUserRoom(username) ?: "general"
        
        val roomDirectory = File("roomChats")
        if (!roomDirectory.exists()) {
            roomDirectory.mkdir()
        }
        
        val roomChatHistory = File("roomChats/$room.txt")
        if (!roomChatHistory.exists()) {
            roomChatHistory.appendText("[" + JSONObject().apply {
                put("type", "beginning")
                put("username", "system")
                put("content", "")
            })
        }
        roomChatHistory.appendText("," + JSONObject().apply {
            put("type", type)
            put("username", username)
            put("content", content)
        })
        
        return "Success"
    } else {
        return "No data provided"
    }
}

fun getRoomChatHistory(roomName: String): String {
    val roomChatFile = File("roomChats/$roomName.txt")
    if (roomChatFile.exists()) {
        return roomChatFile.readText() + "]"
    }
    return ""
}

fun buildHTML(): String {
    try {
        config.getConfig()
        val htmlFile = File("resources/index.html")
        val html = htmlFile.readLines()
        var editedhtml = ""
        for (line in html) {
            if (line == """                    <input type="text" id="serverUrl" value="bobcompass.online" placeholder="Server URL"><br>""") { 
                editedhtml += """                    <input type="text" id="serverUrl" value="${config.address}" placeholder="Server URL"><br>""" 
            } else if (line == """                    <input type="text" id="serverPort" value="443" placeholder="Server Port"><br>""") {
                editedhtml += """                    <input type="text" id="serverPort" value="${config.port}" placeholder="Server Port"><br>"""
            } else if (line == """                    <input type="checkbox" id="securityStatus" checked>""" && config.security == "false") {
                editedhtml += """                    <input type="checkbox" id="securityStatus">"""
            } else if (line == """                    <h3>Chookchat</h3>""") {
                editedhtml += """                    <h3>${config.serviceName}</h3>""" 
            } else if (line == """                    <!-- Eggs Start Here -->""") {
                val eggsFile = File("chookchat.eggs.config")
                val eggs = eggsFile.readLines()
                for (line in eggs) {
                    val eggHTMLFile = File("eggs/$line/index.html")
                    if (eggHTMLFile.exists()) {
                        val eggHTML = eggHTMLFile.readText()
                        editedhtml += eggHTML
                    }
                }
            } else {
                editedhtml += line
            }
        }
        
        return(editedhtml)
    } catch (e: Exception) {
        log(e.toString())
        return("There was an error! If you're the server's admin, here are the details: $e")
    }
    return("dingus")
}

fun buildJS(): String {
    try {
        val eggsFile = File("chookchat.eggs.config")
        val eggs = eggsFile.readLines()
        val jsFile = File("resources/index.js")
        val js = jsFile.readLines()
        var editedJS = ""
        for (line in js) {
            if (line == "            // Egg message logic") {
                for (line in eggs) {
                    val eggJSMessageFile = File("eggs/$line/message.js")
                    if (eggJSMessageFile.exists()) {
                        val eggJSMessage = eggJSMessageFile.readText()
                        editedJS += eggJSMessage
                    }
                }
            } else {
                editedJS += "$line\n"
            }
        }
        for (line in eggs) {
            val eggJSFile = File("eggs/$line/index.js")
            if (eggJSFile.exists()) {
                val eggJS = eggJSFile.readText()
                editedJS += eggJS
            }
        }
        return(editedJS)
    } catch (e: Exception) {
        log(e.toString())
        return("console.log(`There was an error! If you're the server's admin, here are the details: $e`)")
    }
    return("dingus")
}

fun handleServerCommand(command: String): String {
    val commandArgs = mutableListOf("")
    commandArgs.drop(1)
    var currentStage = 0

    for (char in command) {
        if (char == ' ') {
            currentStage ++
            commandArgs += ""
        } else {
            commandArgs[currentStage] += char
        }
    }
    return("I'm not sure how to ${commandArgs.toString()}")
}

fun createAccount(inputData: String): String {
    var username = ""
    var token = ""
    var message = ""
    var dataType = ""
    var isParsingData = 0
    for (char in inputData) {
        val character = char
        if (character == ':') {
            isParsingData = 1
        } else if (isParsingData == 1) {
            if (character == '}') {
                isParsingData = 0
                dataType = ""
            } else if (character != '{') {
                if (dataType == "username") {
                    username += character
                } else if (dataType == "token") {
                    token += character
                } else if (dataType == "message") {
                    message += character
                }
            }
        } else {
            dataType += character
        }
    }
    val userDatabaseParser = BufferedReader(File("userDatabase").reader())
    var lineNumber = 1
    var userExists = 0

    var response = ""
    userDatabaseParser.forEachLine { line ->
        if (line.contains(username)) {
            val processedData = JSONObject().apply {
                put("type", "error")
                put("username", "system")
                put("content", "username-taken")
            }
            response = processedData.toString()
        }
        lineNumber++
    }
    if (response != "") {
        return(response)
    }
    userDatabaseParser.close()
    if (username == "") {
        val processedData = JSONObject().apply {
            put("type", "error")
            put("username", "system")
            put("content", "no-username")
        }
        return(processedData.toString())
    }

    if (token == "") {
        val processedData = JSONObject().apply {
            put("type", "error")
            put("username", "system")
            put("content", "no-token")
        }
        return(processedData.toString())
    }

    val userDatabaseFile = File("userDatabase")
    userDatabaseFile.appendText("${System.lineSeparator()}$username:$token")
    val processedData = JSONObject().apply {
        put("type", "success")
        put("username", "system")
        put("content", "success")
    }
    return(processedData.toString())
}

fun main(args: Array<String>) {
    WsSessionManager.peopleOnline.clear()
    WsSessionManager.sessionsList.clear()
    WsSessionManager.roomList.clear()
    
    WsSessionManager.createRoom("general")
    
    val roomDirectory = File("roomChats")
    if (!roomDirectory.exists()) {
        roomDirectory.mkdir()
    }
    
    val app = Javalin.create { config ->
            config.staticFiles.add("/public")
        }
        .get("/") { ctx ->  
            ctx.html(buildHTML())
        }
        .get("/index.js") { ctx ->
            ctx.result(buildJS())
        }
        .get("/api/createaccount/{content}") { ctx -> 
            ctx.result(createAccount(ctx.pathParam("content")))
        }
        .get("/api/rooms") { ctx ->
            val rooms = WsSessionManager.getRooms()
            val roomsJson = JSONArray(rooms)
            val processedData = JSONObject().apply {
                put("type", "roomsList")
                put("username", "system")
                put("content", roomsJson.toString())
            }
            ctx.result(processedData.toString())
        }
        .get("/api/room/{roomName}/history") { ctx ->
            val roomName = ctx.pathParam("roomName")
            ctx.result(getRoomChatHistory(roomName))
        }
        .post("/api/upload") { ctx ->
            val uploadedFiles = ctx.uploadedFiles()
            if (uploadedFiles.isEmpty()) {
                ctx.status(400).result("No files uploaded")
                return@post
            }
            val uploadedFile = uploadedFiles[0]
            val originalFilename = uploadedFile.filename()
            val uuid = UUID.randomUUID().toString()
            val fileExtension = originalFilename.substringAfterLast(".", "")
            val baseFilename = originalFilename.substringBeforeLast(".")
            val newFilename = "${baseFilename}_${uuid}${if (fileExtension.isNotEmpty()) ".$fileExtension" else ""}"
            val filePath = Paths.get("uploads", newFilename)
            Files.copy(uploadedFile.content(), filePath)
            
            val room = if (ctx.formParam("room") != null) ctx.formParam("room") else "general"
            var username: String = ""
            var token: String = ""

            if (ctx.formParam("username") != null) {
                username = ctx.formParam("username").toString()
            } else {
                // do error
            }

            if (ctx.formParam("token") != null) {
                token = ctx.formParam("token").toString()
            } else {
                // do error
            }
            
            val processedData = JSONObject().apply {
                put("type", "fileStatus")
                put("username", "system")
                put("content", "success")
            }
            ctx.result(processedData.toString())
            
            val processedData2 = JSONObject().apply {
                put("type", "file")
                put("username", username)
                put("room", room)
                put("content", "https://maxwellj.xyz/chookchat/uploads/$newFilename")
            }
            
            if (room != null && room != "general") {
                WsSessionManager.broadcastToRoom(room, processedData2.toString())
            } else {
                WsSessionManager.broadcast(processedData2.toString())
            }
            val roomDirectory = File("roomChats")                                                                                                                                                                      
            if (!roomDirectory.exists()) {                                                                                                                                                                             
                roomDirectory.mkdir()                                                                                                                                                                                  
            }                                                                                                                                                                                                          
                                                                                                                                                                                                                        
            val roomChatHistory = File("roomChats/$room.txt")                                                                                                                                                          
            if (!roomChatHistory.exists()) {                                                                                                                                                                           
                roomChatHistory.appendText("[" + JSONObject().apply {                                                                                                                                                  
                    put("type", "beginning")                                                                                                                                                                           
                    put("username", "system")                                                                                                                                                                          
                    put("content", "")                                                                                                                                                                                 
                })                                                                                                                                                                                                     
            }                                                                                                                                                                                                          
            roomChatHistory.appendText("," + JSONObject().apply {                                                                                                                                                      
                put("type", "file")                                                                                                                                                                                      
                put("username", username)                                                                                                                                                                              
                put("content", "https://maxwellj.xyz/chookchat/uploads/$newFilename")                                                                                                                                                                                
            })  
        }
        .ws("/api/websocket") { ws -> 
            ws.onConnect { ctx -> 
                WsSessionManager.addSession(ctx)
            }
            ws.onClose { ctx ->
                WsSessionManager.removeSession(ctx)
            }
            ws.onMessage { ctx ->
                when (ctx.message()) {
                    "pong" -> {}
                    else -> {
                        log(ctx.message()) 
                        val successState = handleSentMessage(ctx.message())
                        if (successState != "Success") {
                            try {
                                ctx.send(successState)
                            } catch (e: Exception) {
                                log("Error sending error message: ${e.message}")
                            }
                        } else {
                            val messageContent = extractMessageContent(ctx.message(), ctx)
                            
                            try {
                                val jsonMessage = JSONObject(messageContent)
                                if (jsonMessage.has("room")) {
                                    val room = jsonMessage.getString("room")
                                    if (WsSessionManager.roomList.contains(room)) {
                                        WsSessionManager.broadcastToRoom(room, messageContent)
                                    } else {
                                        WsSessionManager.createRoom(room)
                                        WsSessionManager.broadcastToRoom(room, messageContent)
                                    }
                                } else {
                                    WsSessionManager.broadcastToRoom("general", messageContent)
                                }
                            } catch (e: Exception) {
                                log("Error in broadcasting message: ${e.message}")
                                WsSessionManager.broadcastToRoom("general", messageContent)
                            }
                        }
                    }
                }
            }
        }
        .start(7070)
    
    try {
        if (args[0] == "-i") {
            log("Type a command for the server")
            while (1 == 1) {
                log(handleServerCommand(readln()))
            }
        } else {
            println("Interactive mode disabled, add -i to enable")
        }
    } catch (error: Exception) {
        println("Interactive mode disabled, add -i to enable")
    }
}
