package com.correx.core.context.compression

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive

/**
 * Stage 1: free, deterministic format-level compression for structured content. JSON is
 * flattened to dotted `key = value` lines (drops braces, quotes and repeated structural
 * punctuation the model doesn't need); non-JSON content is returned untouched (line-level
 * dedupe is already the ToolLog strategy's job). Exact values are preserved verbatim — this
 * stage is lossless w.r.t. information, it only strips format overhead (pipeline §1).
 */
class FormatCompressor {

    fun compress(content: String): String {
        val trimmed = content.trim()
        if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return content
        return runCatching { json.parseToJsonElement(trimmed) }
            .getOrNull()
            ?.let { flatten(it).takeIf { lines -> lines.isNotEmpty() }?.joinToString("\n") }
            ?: content
    }

    private fun flatten(element: JsonElement, prefix: String = ""): List<String> = when (element) {
        is JsonObject -> element.entries.flatMap { (k, v) -> flatten(v, join(prefix, k)) }
        is JsonArray -> element.flatMapIndexed { i, v -> flatten(v, join(prefix, i.toString())) }
        is JsonPrimitive -> listOf("${prefix.ifEmpty { "value" }} = ${element.content}")
    }

    private fun join(prefix: String, key: String) = if (prefix.isEmpty()) key else "$prefix.$key"

    private companion object {
        val json = Json { ignoreUnknownKeys = true }
    }
}
