import Foundation
import Testing
@testable import Kanban

/// **The sandbox verification the card's design ruling asks for**: "prefer … `Process`+`/usr/bin/
/// ditto` … VERIFY in a sandboxed build".
///
/// `KanbanTests` is host-application-hosted (`TEST_HOST` in `project.yml` points at the built
/// `Lanework.app`), so this suite runs *inside* the real, sandboxed app process —
/// `Kanban.entitlements`'s `com.apple.security.app-sandbox` and all — rather than in a bare XCTest
/// bundle with none of the app's confinement. A green run here is empirical: `/usr/bin/ditto`,
/// spawned as this app's child, can read a folder this process owns and write a `.zip` beside it,
/// under the same entitlements a real File ▸ Share… run would have. That is the closest this suite
/// can get to the real button without driving AppKit (`BoardSharePresentation`'s own boundary).
@Suite("DittoZipArchiver")
struct DittoZipArchiverTests {

    @Test("A folder zips inside the sandbox, and the result is a real zip")
    func zipsInsideTheSandbox() throws {
        let fixture = try WriterFixture()
        defer { fixture.tearDown() }

        let source = fixture.url("Payload")
        try FileManager.default.createDirectory(at: source, withIntermediateDirectories: true)
        try Data("hello from the sandbox\n".utf8).write(to: source.appendingPathComponent("note.txt"))
        try FileManager.default.createDirectory(
            at: source.appendingPathComponent("nested", isDirectory: true),
            withIntermediateDirectories: true
        )
        try Data([0x01, 0x02, 0x03]).write(to: source.appendingPathComponent("nested/data.bin"))

        let destination = fixture.url("Payload.zip")
        try DittoZipArchiver.zip(contentsOf: source, to: destination)

        #expect(FileManager.default.fileExists(atPath: destination.path))
        let bytes = try Data(contentsOf: destination)
        #expect(!bytes.isEmpty)
        // The local file header signature `PK\x03\x04` — proof this is an actual zip archive and
        // not, say, an empty file `ditto` merely touched.
        #expect(bytes.prefix(4) == Data([0x50, 0x4B, 0x03, 0x04]))
    }

    @Test("A source that doesn't exist is a failure, not a silent empty archive")
    func missingSourceFails() throws {
        let fixture = try WriterFixture()
        defer { fixture.tearDown() }
        let missing = fixture.url("Never")
        let destination = fixture.url("Never.zip")

        #expect(throws: DittoZipArchiver.Failure.self) {
            try DittoZipArchiver.zip(contentsOf: missing, to: destination)
        }
        #expect(!FileManager.default.fileExists(atPath: destination.path))
    }
}
