package network

import java.io.File
import java.io.BufferedReader
import java.io.InputStreamReader
import kotlinx.coroutines.*
import java.util.concurrent.ConcurrentHashMap

object LlamaServerManager {
    // 포트별로 프로세스를 관리합니다.
    private val processes = ConcurrentHashMap<Int, Process>()
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    init {
        Runtime.getRuntime().addShutdownHook(Thread {
            stopAll()
        })
    }

    fun startServer(binPath: String, modelPath: String, port: Int, nGpuLayers: Int = 99) {
        // 이미 해당 포트에서 실행 중이거나 모델 경로가 비었으면 무시합니다.
        if (processes.containsKey(port) || modelPath.isBlank()) return

        val command = listOf(
            binPath,
            "-m", modelPath,
            "--port", port.toString(),
            "-c", if (port == 8081) "512" else "4096", // 임베딩용은 컨텍스트가 짧아도 충분합니다.
            "-ngl", nGpuLayers.toString(),
            "-t", "6", // M3 Pro의 성능 코어를 고려하여 6~8개 권장
            "--embedding" // 임베딩 기능을 활성화합니다.
        )

        scope.launch {
            try {
                val pb = ProcessBuilder(command)

                pb.redirectErrorStream(true)
                File(binPath).setExecutable(true)

                val process = pb.start()
                processes[port] = process
                println("✅ AI 서버 시작 시도 (Port: $port, Model: ${File(modelPath).name})")

                val reader = BufferedReader(InputStreamReader(process.inputStream))
                var line: String?
                while (reader.readLine().also { line = it } != null) {
                    // 로그 출력 (디버깅용)
                     println("[Server $port] $line")
                    if (line?.contains("server is listening") == true) {
                        println("🚀 AI 서버 준비 완료 (Port: $port)")
                    }
                }
            } catch (e: Exception) {
                println("❌ AI 서버 실행 실패 (Port: $port): ${e.message}")
                processes.remove(port)
            }
        }
    }

    fun stopAll() {
        processes.forEach { (port, process) ->
            process.destroy()
            println("🛑 AI 서버 종료 (Port: $port)")
        }
        processes.clear()
    }
}