import Testing
@testable import CalcPad

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

    @Test("Evaluate 1000+ line sheet completes in under 1 second")
    func largeSheetEvaluation() async throws {
        // Generate a 1500-line document mixing expressions, blanks, and comments
        var lines: [String] = []
        for i in 1...1500 {
            switch i % 5 {
            case 0: lines.append("") // blank
            case 1: lines.append("// Line \(i)")  // comment
            case 2: lines.append("\(i) + \(i * 2)")
            case 3: lines.append("\(i) * 3")
            case 4: lines.append("\(i) / 7")
            default: lines.append("\(i)")
            }
        }
        let text = lines.joined(separator: "\n")

        let start = ContinuousClock.now
        let results = engine.evaluateSheet(text)
        let elapsed = ContinuousClock.now - start

        #expect(results.count == 1500)
        #expect(elapsed < .seconds(1), "Sheet evaluation took \(elapsed), expected < 1 second")
    }

    @Test("Evaluate 5000 line sheet completes in under 3 seconds")
    func veryLargeSheetEvaluation() async throws {
        var lines: [String] = []
        for i in 1...5000 {
            lines.append("\(i) + \(i)")
        }
        let text = lines.joined(separator: "\n")

        let start = ContinuousClock.now
        let results = engine.evaluateSheet(text)
        let elapsed = ContinuousClock.now - start

        #expect(results.count == 5000)
        #expect(elapsed < .seconds(3), "Sheet evaluation took \(elapsed), expected < 3 seconds")
    }

    @Test("LineResult array construction is efficient for large documents")
    func lineResultConstruction() {
        // Verify we get correct line numbering for large documents
        let lines = (1...1000).map { "\($0) + 1" }
        let text = lines.joined(separator: "\n")
        let results = engine.evaluateSheet(text)

        #expect(results.count == 1000)
        #expect(results.first?.lineNumber == 1)
        #expect(results.last?.lineNumber == 1000)

        // Spot-check results
        #expect(results[0].result == "2")   // 1 + 1
        #expect(results[99].result == "101") // 100 + 1
        #expect(results[999].result == "1001") // 1000 + 1
    }
}
