import Foundation
import Testing
import HostRegistry

// UserDefaultsLastSessionStore over an injectable, per-test-unique suite
// (plan §3.3: 非机密;lastSessionId 存取/清除)。

@Test("lastSessionId 存取:set 后读回同一 UUID")
func setThenGetReturnsSameSessionId() throws {
    // Arrange
    let suiteName = Fixtures.makeSuiteName()
    let defaults = try #require(UserDefaults(suiteName: suiteName))
    defer { defaults.removePersistentDomain(forName: suiteName) }
    let store = UserDefaultsLastSessionStore(defaults: defaults)
    let host = UUID()
    let session = UUID()

    // Act
    store.setLastSessionId(session, host: host)

    // Assert
    #expect(store.lastSessionId(host: host) == session)
}

@Test("未设置过的 host:lastSessionId 返回 nil")
func unknownHostReturnsNil() throws {
    // Arrange
    let suiteName = Fixtures.makeSuiteName()
    let defaults = try #require(UserDefaults(suiteName: suiteName))
    defer { defaults.removePersistentDomain(forName: suiteName) }
    let store = UserDefaultsLastSessionStore(defaults: defaults)

    // Act / Assert
    #expect(store.lastSessionId(host: UUID()) == nil)
}

@Test("set nil:清除既有 lastSessionId")
func settingNilClearsStoredSessionId() throws {
    // Arrange
    let suiteName = Fixtures.makeSuiteName()
    let defaults = try #require(UserDefaults(suiteName: suiteName))
    defer { defaults.removePersistentDomain(forName: suiteName) }
    let store = UserDefaultsLastSessionStore(defaults: defaults)
    let host = UUID()
    store.setLastSessionId(UUID(), host: host)

    // Act
    store.setLastSessionId(nil, host: host)

    // Assert
    #expect(store.lastSessionId(host: host) == nil)
}

@Test("不同 host 键隔离:互不覆盖")
func distinctHostsDoNotCollide() throws {
    // Arrange
    let suiteName = Fixtures.makeSuiteName()
    let defaults = try #require(UserDefaults(suiteName: suiteName))
    defer { defaults.removePersistentDomain(forName: suiteName) }
    let store = UserDefaultsLastSessionStore(defaults: defaults)
    let hostA = UUID()
    let hostB = UUID()
    let sessionA = UUID()
    let sessionB = UUID()

    // Act
    store.setLastSessionId(sessionA, host: hostA)
    store.setLastSessionId(sessionB, host: hostB)

    // Assert
    #expect(store.lastSessionId(host: hostA) == sessionA)
    #expect(store.lastSessionId(host: hostB) == sessionB)
}

@Test("UserDefaults 中的非 UUID 垃圾值:读回 nil 而非 crash(防御性解析)")
func garbageStoredValueReadsBackAsNil() throws {
    // Arrange — discover the store's key via the suite's own domain, then poison it
    let suiteName = Fixtures.makeSuiteName()
    let defaults = try #require(UserDefaults(suiteName: suiteName))
    defer { defaults.removePersistentDomain(forName: suiteName) }
    let store = UserDefaultsLastSessionStore(defaults: defaults)
    let host = UUID()
    store.setLastSessionId(UUID(), host: host)
    let key = try #require(defaults.persistentDomain(forName: suiteName)?.keys.first)

    // Act
    defaults.set("not-a-uuid", forKey: key)

    // Assert
    #expect(store.lastSessionId(host: host) == nil)
}
