package com.bytelyst.platform.diagnostics

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach

class DiagnosticsTypesTest {
    
    @Test
    fun `test DiagnosticsSession creation`() {
        val session = DiagnosticsSession(
            id = "ds_test123",
            productId = "test-app",
            status = DiagnosticsSessionStatus.ACTIVE,
            collectionLevel = DiagnosticsCollectionLevel.DEBUG,
            captureLogs = true,
            captureNetwork = true,
            captureScreenshots = false,
            screenshotOnError = true,
            maxDurationMinutes = 60,
            createdAt = "2026-03-03T12:00:00Z",
            expiresAt = "2026-03-03T13:00:00Z"
        )
        
        assertEquals("ds_test123", session.id)
        assertEquals(DiagnosticsSessionStatus.ACTIVE, session.status)
        assertEquals(DiagnosticsCollectionLevel.DEBUG, session.collectionLevel)
        assertTrue(session.captureLogs)
    }
    
    @Test
    fun `test DiagnosticsLogEntry creation`() {
        val entry = DiagnosticsLogEntry(
            level = DiagnosticsLogLevel.ERROR,
            message = "Something went wrong",
            timestamp = "2026-03-03T12:00:00Z",
            module = "TestModule",
            file = "Test.kt",
            line = 42,
            function = "testFunction",
            context = mapOf("key" to "value"),
            correlationId = "corr-123"
        )
        
        assertEquals(DiagnosticsLogLevel.ERROR, entry.level)
        assertEquals("Something went wrong", entry.message)
        assertEquals(42, entry.line)
    }
    
    @Test
    fun `test DiagnosticsTraceSpan creation`() {
        val span = DiagnosticsTraceSpan(
            spanId = "span-123",
            parentId = "parent-456",
            name = "test-span",
            kind = DiagnosticsSpanKind.INTERNAL,
            startTime = "2026-03-03T12:00:00Z",
            endTime = "2026-03-03T12:00:01Z",
            durationMs = 1000.0,
            attributes = mapOf("key" to "value"),
            status = DiagnosticsSpanStatus.OK
        )
        
        assertEquals("span-123", span.spanId)
        assertEquals("parent-456", span.parentId)
        assertEquals(DiagnosticsSpanStatus.OK, span.status)
    }
    
    @Test
    fun `test DiagnosticsBreadcrumb creation`() {
        val breadcrumb = DiagnosticsBreadcrumb(
            timestamp = "2026-03-03T12:00:00Z",
            category = "navigation",
            message = "User tapped button",
            data = mapOf("buttonId" to "submit")
        )
        
        assertEquals("navigation", breadcrumb.category)
        assertEquals("User tapped button", breadcrumb.message)
    }
    
    @Test
    fun `test DiagnosticsNetworkRequest creation`() {
        val request = DiagnosticsNetworkRequest(
            id = "req-123",
            url = "https://api.example.com/test",
            method = "POST",
            requestHeaders = mapOf("Content-Type" to "application/json"),
            requestBody = "{}",
            status = 200,
            startTime = "2026-03-03T12:00:00Z",
            endTime = "2026-03-03T12:00:01Z",
            durationMs = 100.0
        )
        
        assertEquals("req-123", request.id)
        assertEquals(200, request.status)
        assertEquals(100.0, request.durationMs!!, 0.0)
    }
    
    @Test
    fun `test DiagnosticsDeviceState creation`() {
        val state = DiagnosticsDeviceState(
            memoryMB = 1024,
            batteryLevel = 0.75f,
            isCharging = true,
            storageMB = 512,
            networkType = "wifi",
            isOnline = true,
            thermalState = DiagnosticsThermalState.NOMINAL
        )
        
        assertEquals(1024, state.memoryMB)
        assertEquals(0.75f, state.batteryLevel)
        assertTrue(state.isCharging == true)
        assertEquals(DiagnosticsThermalState.NOMINAL, state.thermalState)
    }
}

class BreadcrumbTrailTest {
    
    private lateinit var trail: BreadcrumbTrail
    
    @BeforeEach
    fun setup() {
        trail = BreadcrumbTrail(maxSize = 3)
    }
    
    @Test
    fun `test add breadcrumb`() {
        trail.add(category = "test", message = "test message")
        assertEquals(1, trail.size())
    }
    
    @Test
    fun `test evict oldest when over limit`() {
        trail.add(category = "a", message = "1")
        trail.add(category = "b", message = "2")
        trail.add(category = "c", message = "3")
        trail.add(category = "d", message = "4")
        
        assertEquals(3, trail.size())
        val all = trail.getAll()
        assertEquals("b", all[0].category) // First one evicted
    }
    
    @Test
    fun `test get last n breadcrumbs`() {
        trail.add(category = "a", message = "1")
        trail.add(category = "b", message = "2")
        trail.add(category = "c", message = "3")
        
        val last2 = trail.getLast(2)
        assertEquals(2, last2.size)
        assertEquals("b", last2[0].category)
    }
    
    @Test
    fun `test get most recent`() {
        trail.add(category = "a", message = "1")
        trail.add(category = "b", message = "2")
        
        val recent = trail.getMostRecent()
        assertEquals("b", recent?.category)
    }
    
    @Test
    fun `test clear`() {
        trail.add(category = "a", message = "1")
        trail.clear()
        assertEquals(0, trail.size())
    }
}

class DiagnosticsConfigurationTest {
    
    @Test
    fun `test configuration creation`() {
        val config = DiagnosticsConfiguration(
            productId = "test-app",
            anonymousInstallId = "install-123",
            platform = "android",
            channel = "android_app",
            osFamily = "android",
            appVersion = "1.0.0",
            buildNumber = "100",
            releaseChannel = "beta",
            serverUrl = "https://api.test.com"
        )
        
        assertEquals("test-app", config.productId)
        assertEquals("install-123", config.anonymousInstallId)
        assertEquals(5000, config.pollIntervalMs) // Default
        assertEquals(100, config.maxBreadcrumbs) // Default
    }
    
    @Test
    fun `test configuration with custom values`() {
        val config = DiagnosticsConfiguration(
            productId = "test-app",
            anonymousInstallId = "install-123",
            platform = "android",
            channel = "android_app",
            osFamily = "android",
            appVersion = "1.0.0",
            buildNumber = "100",
            releaseChannel = "beta",
            serverUrl = "https://api.test.com",
            pollIntervalMs = 10000,
            maxBreadcrumbs = 50
        )
        
        assertEquals(10000, config.pollIntervalMs)
        assertEquals(50, config.maxBreadcrumbs)
    }
}
