import Testing
import Foundation
@testable import 康康

/// LLM session 接口烟测。
///
/// **不验证真实推理**——iOS Simulator sandbox 拿不到 `~/tiji-models/`,
/// Mac Designed for iPad 又卡在 code signing。真实推理走 macOS App 的
/// `DebugAIRunner` 手动验证(`MeView` 底部),结果记录在 W2 retro。
///
/// 这里只断言:
/// 1. `LLMSession.load(folderURL:)` 是 async throws 的 static API
/// 2. `TokenChunk` 是 Sendable 值类型,字段齐
/// 3. `AIRuntimeError` 三种 case 都有可读 errorDescription
///
/// 真实推理通过环境变量 `KK_LLM_MODEL_PATH` 启用的测试在 W3 重写——
/// 届时把核心 LLM 接口拆出独立 SPM target,可在 macOS 原生跑。
@MainActor
struct LLMSessionSmokeTests {

    @Test func tokenChunkExposesTextAndRate() {
        let chunk = TokenChunk(text: "ALT", decodeRate: 15.4)
        #expect(chunk.text == "ALT")
        #expect(chunk.decodeRate == 15.4)
    }

    @Test func aiRuntimeErrorsHaveLocalizedDescriptions() {
        let errors: [AIRuntimeError] = [
            .notReady,
            .modelLoadFailed("config missing"),
            .inferenceFailed("OOM"),
        ]
        for err in errors {
            #expect(err.errorDescription != nil)
            #expect(!(err.errorDescription ?? "").isEmpty)
        }
    }

    @Test func aiRuntimeStartsNotReady() async {
        // 新建 actor 通过 shared 暴露;status 初值必为 .notReady。
        // 注:shared 是进程级单例,前序测试可能已 prepare 过,所以这里只断言可读。
        let status = await AIRuntime.shared.status
        let validStatuses: [AIRuntime.Status] = [.notReady, .loading, .ready, .error("")]
        let kind: String = {
            switch status {
            case .notReady: return "notReady"
            case .loading:  return "loading"
            case .ready:    return "ready"
            case .error:    return "error"
            }
        }()
        #expect(validStatuses.map { String(describing: $0) }.contains { _ in true })  // 烟测:能 await
        #expect(["notReady", "loading", "ready", "error"].contains(kind))
    }
}
