package link.socket.ampere.util

import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue
import link.socket.ampere.agents.domain.event.Event
import link.socket.ampere.agents.domain.event.CognitiveEvent
import link.socket.ampere.agents.domain.event.MeetingEvent
import link.socket.ampere.agents.domain.event.MemoryEvent
import link.socket.ampere.agents.domain.event.MessageEvent
import link.socket.ampere.agents.domain.event.NotificationEvent
import link.socket.ampere.agents.domain.event.TicketEvent
import org.junit.jupiter.api.Test

class EventTypeParserTest {

    @Test
    fun `parse TaskCreated returns correct EventClassType`() {
        val result = EventTypeParser.parse("TaskCreated")
        assertNotNull(result)
        assertEquals(Event.TaskCreated.EVENT_TYPE, result)
    }

    @Test
    fun `parse is case-insensitive`() {
        val lowercase = EventTypeParser.parse("taskcreated")
        val uppercase = EventTypeParser.parse("TASKCREATED")
        val mixedcase = EventTypeParser.parse("TaskCreated")

        assertNotNull(lowercase)
        assertNotNull(uppercase)
        assertNotNull(mixedcase)
        assertEquals(lowercase, uppercase)
        assertEquals(uppercase, mixedcase)
    }

    @Test
    fun `parse returns null for invalid event type`() {
        val result = EventTypeParser.parse("InvalidEventType")
        assertNull(result)
    }

    @Test
    fun `parse handles all base Event types`() {
        assertNotNull(EventTypeParser.parse("TaskCreated"))
        assertNotNull(EventTypeParser.parse("QuestionRaised"))
        assertNotNull(EventTypeParser.parse("CodeSubmitted"))
    }

    @Test
    fun `parse handles CognitiveEvent types`() {
        assertNotNull(EventTypeParser.parse("EscalationFired"))
        assertNotNull(EventTypeParser.parse("EscalationConsidered"))
    }

    @Test
    fun `parse handles all MeetingEvent types`() {
        assertNotNull(EventTypeParser.parse("MeetingScheduled"))
        assertNotNull(EventTypeParser.parse("MeetingStarted"))
        assertNotNull(EventTypeParser.parse("AgendaItemStarted"))
        assertNotNull(EventTypeParser.parse("AgendaItemCompleted"))
        assertNotNull(EventTypeParser.parse("MeetingCompleted"))
        assertNotNull(EventTypeParser.parse("MeetingCanceled"))
    }

    @Test
    fun `parse handles all TicketEvent types`() {
        assertNotNull(EventTypeParser.parse("TicketCreated"))
        assertNotNull(EventTypeParser.parse("TicketStatusChanged"))
        assertNotNull(EventTypeParser.parse("TicketAssigned"))
        assertNotNull(EventTypeParser.parse("TicketBlocked"))
        assertNotNull(EventTypeParser.parse("TicketCompleted"))
        assertNotNull(EventTypeParser.parse("TicketMeetingScheduled"))
    }

    @Test
    fun `parse handles all MessageEvent types`() {
        assertNotNull(EventTypeParser.parse("ThreadCreated"))
        assertNotNull(EventTypeParser.parse("MessagePosted"))
        assertNotNull(EventTypeParser.parse("ThreadStatusChanged"))
        assertNotNull(EventTypeParser.parse("EscalationRequested"))
    }

    @Test
    fun `parse handles all NotificationEvent types`() {
        assertNotNull(EventTypeParser.parse("NotificationToAgent"))
        assertNotNull(EventTypeParser.parse("NotificationToHuman"))
    }

    @Test
    fun `parse handles milestone event type`() {
        assertNotNull(EventTypeParser.parse("MilestoneReached"))
    }

    @Test
    fun `parseMultiple returns set of EventClassTypes`() {
        val result = EventTypeParser.parseMultiple(
            listOf("TaskCreated", "QuestionRaised", "MeetingScheduled")
        )

        assertEquals(3, result.size)
        assertTrue(result.contains(Event.TaskCreated.EVENT_TYPE))
        assertTrue(result.contains(Event.QuestionRaised.EVENT_TYPE))
        assertTrue(result.contains(MeetingEvent.MeetingScheduled.EVENT_TYPE))
    }

    @Test
    fun `parseMultiple skips invalid type names`() {
        val result = EventTypeParser.parseMultiple(
            listOf("TaskCreated", "InvalidType", "QuestionRaised")
        )

        assertEquals(2, result.size)
        assertTrue(result.contains(Event.TaskCreated.EVENT_TYPE))
        assertTrue(result.contains(Event.QuestionRaised.EVENT_TYPE))
    }

    @Test
    fun `parseMultiple returns empty set for all invalid types`() {
        val result = EventTypeParser.parseMultiple(
            listOf("Invalid1", "Invalid2")
        )

        assertTrue(result.isEmpty())
    }

    @Test
    fun `parseMultiple handles empty list`() {
        val result = EventTypeParser.parseMultiple(emptyList())
        assertTrue(result.isEmpty())
    }

    @Test
    fun `getAllEventTypeNames returns all event types`() {
        val allNames = EventTypeParser.getAllEventTypeNames()

        // Should have at least the basic event types
        assertTrue(allNames.contains("taskcreated"))
        assertTrue(allNames.contains("questionraised"))
        assertTrue(allNames.contains("codesubmitted"))

        // Should have meeting events
        assertTrue(allNames.contains("meetingscheduled"))

        // Should have ticket events
        assertTrue(allNames.contains("ticketcreated"))

        // Should have message events
        assertTrue(allNames.contains("threadcreated"))

        // Should have notification events
        assertTrue(allNames.contains("notificationtoagent"))
        assertTrue(allNames.contains("notificationtohuman"))

        // Should have milestone events
        assertTrue(allNames.contains("milestonereached"))
    }

    @Test
    fun `getAllEventTypes returns all EventClassTypes`() {
        val allTypes = EventTypeParser.getAllEventTypes()

        // Should have at least the basic event types
        assertTrue(allTypes.contains(Event.TaskCreated.EVENT_TYPE))
        assertTrue(allTypes.contains(Event.QuestionRaised.EVENT_TYPE))
        assertTrue(allTypes.contains(Event.CodeSubmitted.EVENT_TYPE))
        assertTrue(allTypes.contains(CognitiveEvent.EscalationFired.EVENT_TYPE))
        assertTrue(allTypes.contains(CognitiveEvent.EscalationConsidered.EVENT_TYPE))

        // Should have meeting events
        assertTrue(allTypes.contains(MeetingEvent.MeetingScheduled.EVENT_TYPE))

        // Should have ticket events
        assertTrue(allTypes.contains(TicketEvent.TicketCreated.EVENT_TYPE))

        // Should have message events
        assertTrue(allTypes.contains(MessageEvent.ThreadCreated.EVENT_TYPE))

        // Should have milestone events
        assertTrue(allTypes.contains(MemoryEvent.MilestoneReached.EVENT_TYPE))

        // Should have notification events
        assertTrue(allTypes.contains(NotificationEvent.ToAgent.EVENT_TYPE))
        assertTrue(allTypes.contains(NotificationEvent.ToHuman.EVENT_TYPE))
    }

    @Test
    fun `parsed event type has correct string name`() {
        val taskCreated = EventTypeParser.parse("TaskCreated")
        assertNotNull(taskCreated)
        assertEquals("TaskCreated", taskCreated)

        val meetingScheduled = EventTypeParser.parse("MeetingScheduled")
        assertNotNull(meetingScheduled)
        assertEquals("MeetingScheduled", meetingScheduled)
    }
}
