package ActiveMQ

import config
import jakarta.jms.BytesMessage
import jakarta.jms.Connection
import jakarta.jms.MapMessage
import jakarta.jms.Message
import jakarta.jms.MessageConsumer
import jakarta.jms.MessageListener
import jakarta.jms.Queue
import jakarta.jms.Session
import jakarta.jms.TextMessage
import org.apache.activemq.ActiveMQConnectionFactory
import org.tinylog.Logger
import java.util.function.Consumer

@Suppress("unused")
class ActiveMQClient {
    private var connection: Connection? = null
    private var session: Session? = null
    private var destination : Queue? = null
    private var consumer: MessageConsumer? = null
    var MessageConsumer : Consumer<Message>?= null

    /**
     * Start ActiveMQ Connection
     */
    fun Start(){
        try{
            connection = ActiveMQConnectionFactory(config.ActiveMQ_BrokerURL, config.ActiveMQ_Username, config.ActiveMQ_Password).createConnection()
            connection?.start()
            session = connection?.createSession(false, Session.AUTO_ACKNOWLEDGE)
            destination = session?.createQueue(config.ActiveMQ_QueueName)
            consumer = session?.createConsumer(destination)
            consumer?.messageListener = MessageListener { message ->
                MessageConsumer?.accept(message)
                when (message) {
                    is TextMessage -> Logger.info { "Received Text Message : ${message.text}" }
                    is BytesMessage -> {
                        val length = message.bodyLength.toInt()
                        val byteArray = ByteArray(length)
                        message.readBytes(byteArray)
                        Logger.info { "Received Bytes Message of length : $length" }
                    }

                    is MapMessage -> {
                        val mapNames = message.mapNames
                        val mapContent = mutableMapOf<String, Any?>()
                        while (mapNames.hasMoreElements()) {
                            val key = mapNames.nextElement() as String
                            val value = message.getObject(key)
                            mapContent[key] = value
                        }
                        Logger.info { "Received Map Message : $mapContent" }
                    }

                    else -> Logger.warn { "Received Unknown Message Type" }
                }

            }
            Logger.info { "ActiveMQ Connection created to Broker : ${config.ActiveMQ_BrokerURL}" }
        } catch (e : Exception){
            Logger.error { "Failed to create connection, Message : ${e.message}" }
        }
    }

    /**
     * Stop ActiveMQ Connection
     */
    fun Stop(){
        try{
            if (consumer==null) throw Exception("Consumer is null")
            if (session==null) throw Exception("Session is null")
            if (connection==null) throw Exception("Connection is null")
            consumer?.close()
            session?.close()
            connection?.close()
            Logger.info { "Connection closed to Broker" }
        } catch (e : Exception){
            Logger.error { "Failed to close connection, Message : ${e.message}" }
        }
    }
}