import Foundation
import Testing
@testable import INoteSync

@Suite("AppleScript script generation")
struct AppleScriptTests {
    @Test("scriptForCreate escapes quotes and backslashes in name, body, folder")
    func createEscapes() {
        let script = AppleScriptNoteApplier.scriptForCreate(
            name: "He said \"hi\"",
            body: "line1\nline2 with \\ backslash",
            folder: "Folder \"X\""
        )
        // Every raw user-supplied double quote must have been escaped to \"
        // before being embedded. Verify no occurrence of a bare `"hi"` style
        // sequence leaks into the script.
        #expect(!script.contains("said \"hi\""))
        #expect(script.contains("He said \\\"hi\\\""))
        // Backslash should have been doubled.
        #expect(script.contains("line2 with \\\\ backslash"))
        // Newline should have been escaped to literal \n.
        #expect(!script.contains("line1\nline2"))
        #expect(script.contains("line1\\nline2"))
        // Folder name with quotes escaped.
        #expect(script.contains("Folder \\\"X\\\""))
    }

    @Test("scriptForUpdate with both name and body emits two set statements")
    func updateBoth() {
        let script = AppleScriptNoteApplier.scriptForUpdate(
            id: "x-coredata://abc",
            name: "New Name",
            body: "<p>hi</p>"
        )
        #expect(script.contains("set name of note id \"x-coredata://abc\" to \"New Name\""))
        #expect(script.contains("set body of note id \"x-coredata://abc\" to \"<p>hi</p>\""))
    }

    @Test("scriptForUpdate with only body emits only the body setter")
    func updateBodyOnly() {
        let script = AppleScriptNoteApplier.scriptForUpdate(
            id: "id-1",
            name: nil,
            body: "<p>new</p>"
        )
        #expect(!script.contains("set name of note"))
        #expect(script.contains("set body of note id \"id-1\" to \"<p>new</p>\""))
    }

    @Test("scriptForUpdate escapes injected quotes in id")
    func updateIdEscapes() {
        let script = AppleScriptNoteApplier.scriptForUpdate(
            id: "id with \" quote",
            name: "n",
            body: nil
        )
        #expect(script.contains("id with \\\" quote"))
    }

    @Test("scriptForDelete escapes the id")
    func deleteEscapes() {
        let script = AppleScriptNoteApplier.scriptForDelete(id: "id-\"-1")
        #expect(script.contains("delete note id \"id-\\\"-1\""))
    }

    @Test("parse handles a single well-formed record")
    func parseSingle() {
        let raw = "id-1\u{001F}Name\u{001F}<p>Body</p>\u{001F}Folder\u{001F}2026-05-13T12:00:00Z\u{001E}"
        let notes = NotesReader.parse(raw)
        #expect(notes.count == 1)
        #expect(notes[0].noteIdentifier == "id-1")
        #expect(notes[0].name == "Name")
        #expect(notes[0].body == "<p>Body</p>")
        #expect(notes[0].folder == "Folder")
        #expect(notes[0].modificationDate != nil)
    }

    @Test("parse skips malformed records but keeps valid ones")
    func parseMalformed() {
        let valid = "id-1\u{001F}N\u{001F}B\u{001F}F\u{001F}\u{001E}"
        let malformed = "only-two\u{001F}fields\u{001E}"
        let notes = NotesReader.parse(malformed + valid)
        #expect(notes.count == 1)
        #expect(notes[0].noteIdentifier == "id-1")
        #expect(notes[0].modificationDate == nil)
    }
}
