import Foundation
import Testing
@testable import Kanban

/// **Where app-side state lives** (`AppStateHome`; 02-architecture.md § Per-board app state,
/// "App-wide state has the same home"; 12-editions.md ▸ App-side state, re-ruled 2026-07-30 — one
/// app, one sandbox, one home).
///
/// Two claims, and they are the only two this type makes: the three file stores are neighbours under
/// one directory the app can actually create, and a **unit-test host never resolves to the real
/// one**. The second is not a nicety — the test host *is* the app, so `KanbanApp.init()` runs for
/// real on every test launch, and a home that pointed at the developer's own state would have the
/// host's launch sweep collecting real staged clipboard trees and its recents refresh rewriting real
/// records. There is no injection point in `App.init` to fix that from outside.

@MainActor
@Suite("App state home")
struct AppStateHomeTests {

    @Test("Every app-side store resolves under one state directory, and it is creatable")
    func stateDirectoryIsOneHomeAndAlwaysUsable() throws {
        let home = AppStateHome.directory

        // The registry, the clipboard's staging store and the template store are one another's
        // neighbours by design, and each names the home rather than spelling a path — so this is the
        // assertion that keeps them moving together the day the home moves.
        #expect(BoardRegistry.defaultStorageURL.deletingLastPathComponent() == home)
        #expect(ClipboardStore.defaultStagingRoot.deletingLastPathComponent() == home)
        #expect(TemplateEngine.userStore.deletingLastPathComponent() == home)

        // And it is a directory the app can actually create, which is the one property that has to
        // hold whichever side of the test-host redirect this is running on.
        try FileManager.default.createDirectory(at: home, withIntermediateDirectories: true)
        #expect(FileManager.default.fileExists(atPath: home.path))
    }

    @Test("A unit-test host never resolves to the real Application Support home")
    func aTestHostIsRedirected() {
        // This suite is running, so this *is* a test host — and the point of the check is that the
        // two defaults every launch reaches for (the registry file, the staging root) cannot land in
        // the home the developer's own running copy uses.
        #expect(AppStateHome.isUnitTestHost)
        #expect(AppStateHome.directory == AppStateHome.unitTestDirectory)
        #expect(AppStateHome.directory != AppStateHome.productionDirectory)
    }

    @Test("The production home is Application Support itself, with no bundle-id subfolder appended")
    func productionHomeHasNoBundleIDSubfolder() {
        // The sandbox already scopes `Application Support` to this app — that container path is the
        // one place the bundle id belongs — so a subfolder appended *inside* it would name the app
        // twice. The last component is therefore the check: what this type adds is nothing.
        #expect(AppStateHome.productionDirectory.lastPathComponent == "Application Support")
    }
}
