import Testing
@testable import CalcPad

@Suite("StubCalculationEngine Tests")
struct StubEngineTests {
    let engine = StubCalculationEngine()

    @Test("Blank lines produce nil result")
    func blankLine() {
        let result = engine.evaluateLine("")
        #expect(result.result == nil)
        #expect(result.isError == false)
        #expect(result.isEmpty == true)
    }

    @Test("Whitespace-only lines produce nil result")
    func whitespaceOnly() {
        let result = engine.evaluateLine("   ")
        #expect(result.result == nil)
        #expect(result.isError == false)
    }

    @Test("Comment lines starting with // produce nil result")
    func doubleSlashComment() {
        let result = engine.evaluateLine("// this is a comment")
        #expect(result.result == nil)
        #expect(result.isError == false)
    }

    @Test("Comment lines starting with # produce nil result")
    func hashComment() {
        let result = engine.evaluateLine("# header")
        #expect(result.result == nil)
        #expect(result.isError == false)
    }

    @Test("Simple addition")
    func addition() {
        let result = engine.evaluateLine("2 + 3")
        #expect(result.result == "5")
        #expect(result.isError == false)
    }

    @Test("Simple subtraction")
    func subtraction() {
        let result = engine.evaluateLine("10 - 4")
        #expect(result.result == "6")
        #expect(result.isError == false)
    }

    @Test("Simple multiplication")
    func multiplication() {
        let result = engine.evaluateLine("6 * 7")
        #expect(result.result == "42")
        #expect(result.isError == false)
    }

    @Test("Simple division")
    func division() {
        let result = engine.evaluateLine("15 / 3")
        #expect(result.result == "5")
        #expect(result.isError == false)
    }

    @Test("Decimal result")
    func decimalResult() {
        let result = engine.evaluateLine("7 / 2")
        #expect(result.result == "3.5")
        #expect(result.isError == false)
    }

    @Test("evaluateSheet returns one result per line")
    func evaluateSheet() {
        let text = "2 + 2\n\n10 * 3"
        let results = engine.evaluateSheet(text)
        #expect(results.count == 3)
        #expect(results[0].lineNumber == 1)
        #expect(results[0].result == "4")
        #expect(results[1].lineNumber == 2)
        #expect(results[1].result == nil)
        #expect(results[2].lineNumber == 3)
        #expect(results[2].result == "30")
    }

    @Test("evaluateSheet with comments and blanks")
    func evaluateSheetMixed() {
        let text = "// Title\n5 + 5\n\n# Section\n3 * 3"
        let results = engine.evaluateSheet(text)
        #expect(results.count == 5)
        #expect(results[0].result == nil) // comment
        #expect(results[1].result == "10")
        #expect(results[2].result == nil) // blank
        #expect(results[3].result == nil) // comment
        #expect(results[4].result == "9")
    }

    @Test("LineResult id equals line number")
    func lineResultId() {
        let result = LineResult(id: 5, expression: "2+2", result: "4", isError: false)
        #expect(result.lineNumber == 5)
        #expect(result.id == 5)
    }

    @Test("LineResult isEmpty for nil results")
    func lineResultIsEmpty() {
        let empty = LineResult(id: 1, expression: "", result: nil, isError: false)
        #expect(empty.isEmpty == true)

        let error = LineResult(id: 1, expression: "bad", result: nil, isError: true)
        #expect(error.isEmpty == false)

        let hasResult = LineResult(id: 1, expression: "2+2", result: "4", isError: false)
        #expect(hasResult.isEmpty == false)
    }
}
