import CoreGraphics
import Foundation
import Testing

@testable import VMAgentCore

// MARK: - NDJSON line framing

@Test func lineSplitterYieldsCompleteLines() {
    var buffer = LineSplitBuffer()
    buffer.append(Data("{\"op\":\"pi".utf8))
    #expect(buffer.nextLine() == nil)
    buffer.append(Data("ng\"}\n{\"op\":".utf8))
    #expect(buffer.nextLine() == Data("{\"op\":\"ping\"}".utf8))
    #expect(buffer.nextLine() == nil)
    buffer.append(Data("\"click\"}\n".utf8))
    #expect(buffer.nextLine() == Data("{\"op\":\"click\"}".utf8))
    #expect(buffer.nextLine() == nil)
    #expect(buffer.pendingBytes == 0)
}

@Test func lineSplitterHandlesCRLFAndEmptyLines() {
    var buffer = LineSplitBuffer()
    buffer.append(Data("a\r\n\nb\n".utf8))
    #expect(buffer.nextLine() == Data("a".utf8))
    #expect(buffer.nextLine() == Data())
    #expect(buffer.nextLine() == Data("b".utf8))
    #expect(buffer.nextLine() == nil)
}

@Test func lineSplitterTracksPendingBytes() {
    var buffer = LineSplitBuffer()
    buffer.append(Data(repeating: UInt8(ascii: "x"), count: 100))
    #expect(buffer.pendingBytes == 100)
    #expect(buffer.nextLine() == nil)
}

// MARK: - Key chords

@Test func chordParsesModifiersAndKey() {
    let stroke = KeyMap.stroke(forChord: "cmd+shift+s")
    #expect(stroke == KeyStroke(keyCode: 0x01, flags: [.maskCommand, .maskShift]))
}

@Test func chordParsesBareSpecialKeys() {
    #expect(KeyMap.stroke(forChord: "return") == KeyStroke(keyCode: 0x24, flags: []))
    #expect(KeyMap.stroke(forChord: "enter") == KeyStroke(keyCode: 0x24, flags: []))
    #expect(KeyMap.stroke(forChord: "escape") == KeyStroke(keyCode: 0x35, flags: []))
    #expect(KeyMap.stroke(forChord: "backspace") == KeyStroke(keyCode: 0x33, flags: []))
    #expect(KeyMap.stroke(forChord: "tab") == KeyStroke(keyCode: 0x30, flags: []))
}

@Test func chordParsesArrowAliasesAndFKeys() {
    #expect(KeyMap.stroke(forChord: "arrowdown") == KeyMap.stroke(forChord: "down"))
    #expect(KeyMap.stroke(forChord: "f5") == KeyStroke(keyCode: 0x60, flags: []))
    #expect(KeyMap.stroke(forChord: "cmd+shift+4") == KeyStroke(
        keyCode: 0x15, flags: [.maskCommand, .maskShift]))
}

@Test func chordIsCaseInsensitiveAndToleratesUnknownModifiers() {
    #expect(KeyMap.stroke(forChord: "CMD+S") == KeyStroke(keyCode: 0x01, flags: [.maskCommand]))
    // Unknown modifier tokens are dropped (host-side leniency parity), the key still lands.
    #expect(KeyMap.stroke(forChord: "hyper+s") == KeyStroke(keyCode: 0x01, flags: []))
}

@Test func chordRejectsUnknownKey() {
    #expect(KeyMap.stroke(forChord: "cmd+definitely-not-a-key") == nil)
    #expect(KeyMap.stroke(forChord: "") == nil)
}
