import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.io.Writer
import java.net.ServerSocket
import java.net.Socket
import java.util.ArrayList
import java.util.Collections

class ChatServer private constructor(private val port: Int) : Runnable {
    private val clients = ArrayList<Client>()

    private val onlineListCSV: String
        @Synchronized get() {
            val sb = StringBuilder()
            sb.append(clients.size).append(" user(s) online: ")
            for (i in clients.indices) {
                sb.append(if (i > 0) ", " else "").append(clients[i].clientName)
            }
            return sb.toString()
        }

    override fun run() {
        try {
            val ss = ServerSocket(port)
            while (true) {
                val s = ss.accept()
                Thread(Client(s)).start()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    @Synchronized
    private fun registerClient(client: Client): Boolean {
        for (otherClient in clients) {
            if (otherClient.clientName!!.equals(client.clientName!!, ignoreCase = true)) {
                return false
            }
        }
        clients.add(client)
        return true
    }

    private fun deRegisterClient(client: Client) {
        var wasRegistered = false
        synchronized(this) {
            wasRegistered = clients.remove(client)
        }
        if (wasRegistered) {
            broadcast(client, "--- " + client.clientName + " left ---")
        }
    }

    private fun broadcast(fromClient: Client, msg: String) {