package com.bytelyst.platform.diagnostics

import kotlinx.serialization.Serializable

/**
 * Log severity levels (matches syslog/OpenTelemetry)
 */
enum class DiagnosticsLogLevel {
    DEBUG, INFO, WARN, ERROR, FATAL
}

/**
 * Session status from the server
 */
enum class DiagnosticsSessionStatus {
    PENDING, ACTIVE, PAUSED, COMPLETED, CANCELLED
}

/**
 * Collection level determines verbosity of captured data
 */
enum class DiagnosticsCollectionLevel {
    STANDARD, DEBUG, TRACE
}

/**
 * Diagnostic session configuration from server
 */
@Serializable
data class DiagnosticsSession(
    val id: String,
    val productId: String,
    val status: DiagnosticsSessionStatus,
    val collectionLevel: DiagnosticsCollectionLevel,
    val captureLogs: Boolean,
    val captureNetwork: Boolean,
    val captureScreenshots: Boolean,
    val screenshotOnError: Boolean,
    val maxDurationMinutes: Int,
    val createdAt: String,
    val expiresAt: String
)

/**
 * Span kind for OpenTelemetry compatibility
 */
enum class DiagnosticsSpanKind {
    INTERNAL, SERVER, CLIENT, PRODUCER, CONSUMER
}

/**
 * Span status
 */
enum class DiagnosticsSpanStatus {
    OK, ERROR, UNSET
}

/**
 * OpenTelemetry-compatible trace span
 */
@Serializable
data class DiagnosticsTraceSpan(
    val spanId: String,
    val parentId: String? = null,
    val name: String,
    val kind: DiagnosticsSpanKind? = null,
    val startTime: String,
    val endTime: String? = null,
    val durationMs: Double? = null,
    val attributes: Map<String, String> = emptyMap(),
    val status: DiagnosticsSpanStatus,
    val statusMessage: String? = null
)

/**
 * Structured log entry
 */
@Serializable
data class DiagnosticsLogEntry(
    val level: DiagnosticsLogLevel,
    val message: String,
    val timestamp: String,
    val module: String,
    val file: String? = null,
    val line: Int? = null,
    val function: String? = null,
    val context: Map<String, String> = emptyMap(),
    val correlationId: String? = null
)

/**
 * Breadcrumb for timeline navigation
 */
@Serializable
data class DiagnosticsBreadcrumb(
    val timestamp: String,
    val category: String,
    val message: String,
    val data: Map<String, String>? = null
)

/**
 * Network request/response capture
 */
@Serializable
data class DiagnosticsNetworkRequest(
    val id: String,
    val url: String,
    val method: String,
    val requestHeaders: Map<String, String> = emptyMap(),
    val requestBody: String? = null,
    val status: Int? = null,
    val responseHeaders: Map<String, String>? = null,
    val responseBody: String? = null,
    val startTime: String,
    val endTime: String? = null,
    val durationMs: Double? = null,
    val error: String? = null
)

/**
 * Device state snapshot
 */
@Serializable
data class DiagnosticsDeviceState(
    val memoryMB: Int? = null,
    val batteryLevel: Float? = null,
    val isCharging: Boolean? = null,
    val storageMB: Int? = null,
    val networkType: String? = null,
    val isOnline: Boolean,
    val thermalState: DiagnosticsThermalState? = null
)

/**
 * Thermal state
 */
enum class DiagnosticsThermalState {
    NOMINAL, FAIR, SERIOUS, CRITICAL
}

/**
 * Ingest batch for sending to server
 */
@Serializable
data class DiagnosticsIngestBatch(
    val sessionId: String,
    val traces: List<DiagnosticsTraceSpan>? = null,
    val logs: List<DiagnosticsLogEntry>? = null,
    val breadcrumbs: List<DiagnosticsBreadcrumb>? = null,
    val network: List<DiagnosticsNetworkRequest>? = null
)
