//
//  lkfcSatzartA.swift
//  lkfcTests
//
//  Created by Alexander Holzer on 24.07.25.
//  Copyright © 2025 Alexander Holzer. All rights reserved.
//

import XCTest
@testable import lkfc

final class lkfcSatzartA: XCTestCase {

    
    func createContextWith (model: UInt32, year: Int32? = nil, flags: Int32 = 0, lines : [String]) throws -> LKFContext {
        let c = try lkfcTests.createContextWith(model:model, flags: flags, lines:lines)
        if let year {
            c.setContextParameters(year: year)
        }
        return c
    }
    
    func createContextWith (metaDataContext: LKFMetaDataFilesContext, year: Int32? = nil, lines : [String]) throws -> LKFContext {
        
        let context = try LKFContext (metaDataContext: metaDataContext)
        do {
            for s in lines {
                try context.addLine(line: s)
            }
        }
        catch {
            print (error.localizedDescription)
        }
        return context
    }
    
    static func createContextWith (model: UInt32, year: Int32? = nil, flags : Int32 = 0, cp1252Lines : [String]) throws -> LKFContext {
        let context = try LKFContext(model: model, path: LKFTest.rootPath)
        context.flags = flags
        if let year {
            context.setContextParameters(year: year)
        }
        for s in cp1252Lines {
            _ = context.addwindowsCP1252(line: s)
        }
        return context
    }
    
    func combine (_ first:[String], _ second:[String]) -> [String] {
        return lkfcTests.combine(first, second)
    }
    
    override func setUpWithError() throws {
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDownWithError() throws {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
    }

    static var fall1 = [
         "K01|2025|K901.1|12718100|100|Test|A",
    //     "K08|2025|K989|12718100|42|43|1700|15,79|2,36|0|17,68|0|7,67|2,83|0|2,13|3802630|639108|54694|331526|95668|0|200540|201149|375422|686420|788345|1682024|0|0|0|8857526",
         "X01|K901|123||20250101|1011|S|19660303|55|M|AT|AT|1040|91001|A|P||||E|20250701|1014|SZ|N|5",
         "X02|K901|123||20250101|001|12718100|20250101|1011||20250701||1|||N|55||00001",
         "X03|K901|123||20250101|N39.0|H|||||00001"]
    
    //     "A01|2025|1|K901|12718100|DE|1234567890|Test1|2.222|50|Stk|ATC1",
    //     "A01|2025|1|K901|12718100|DE|1234567890|Test1|1.2|10|Stk|ATC1"]
    
    func testA () throws {
        
        let minYear : UInt32 = 2025
        
        var context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                                                                ["A01||1|K989|12718100|DE|1234567890|Test1|2,22|50|Stück|J05AX31"]))
        try context.execute()
        var errors = context.errorsWith (code:"FAT0")
        XCTAssert(errors != nil, "FAT0 expected in model 2026")
        
        context = try createContextWith(model: minYear - 1, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                                                                ["A01||1|K989|12718100|DE|1234567890|Test1|2,22|50|Stück|J05AX31"]))
        try context.execute()
        errors = context.errorsWith (code:"FAT0")
        XCTAssert(errors == nil, "EA03 not expected in model 2025")

        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                                                                ["A01||1||12718100|DE|1234567890|Test1|2,22|50|Stück|J05AX31"]))
        try context.execute()
        errors = context.errorsWith (code:"FAT1")
        XCTAssert(errors != nil, "FAT0 expected in model 2026")
        
        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                                                            ["A01||1|K901|12718100|DE|1234567890|Test1|2,22|50|Stück|J05AX31"]))
        try context.execute()
        errors = context.errorsWith (code:"EA01")
        XCTAssert(errors != nil, "EA01 expected")
        
        errors = context.errorsWith (code:"EA0E")
        XCTAssert(errors == nil, "EA0E not expected")
        
        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2024|1|K901|12718100|DE|1234567890|Test1|2,221|50|Stück|J05AX31"]))
        try context.execute()
        errors = context.errorsWith (code:"EA02")
        XCTAssert(errors != nil, "EA02 expected")
        errors = context.errorsWith (code:"EA0A")
        XCTAssert(errors != nil, "EA0A expected")
        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2025|01|K901|12718100|DE|1234567890|Test1|-2|50|Stück|P01AB04"]))
        try context.execute()
        errors = context.errorsWith (code:"EA03")
        XCTAssert(errors != nil, "EA03 expected")
        errors = context.errorsWith (code:"EA0A")
        XCTAssert(errors == nil, "EA0A not expected") /* negative values allow with 2026.1 */

        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2025|01|K901|12718100|DE|1234567890|Test1|-0|50|Stück|P01AB04"]))
        try context.execute()
        errors = context.errorsWith (code:"EA03")
        XCTAssert(errors != nil, "EA03 expected")
        errors = context.errorsWith (code:"EA0A")
        XCTAssert(errors != nil, "EA0A expected")

        
        context = try createContextWith(model: minYear - 1, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2025|3|K901|12718100|DE|1234567890|Test1|2,221|50|Stück|P01AB07"]))
        try context.execute()
        errors = context.errorsWith (code:"EA03")
        XCTAssert(errors == nil, "EA03 not expected")

        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2025|1|K901||DE|1234567890|Test1||50|Stück|J05AX26"]))
        try context.execute()
        errors = context.errorsWith (code:"FAT3")
        XCTAssert(errors != nil, "FAT3 expected")
        
        errors = context.errorsWith (code:"EA09")
        XCTAssert(errors != nil, "EA0E expected")

        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2025|1|K901|12345678|DE|1234567890|Test1|2.22|50|Stück"]))
        try context.execute()
        errors = context.errorsWith (code:"FAT2")
        XCTAssert(errors != nil, "FAT2 expected")
        
        errors = context.errorsWith (code:"EA04")
        XCTAssert(errors != nil, "EA04 expected")
        
        errors = context.errorsWith (code:"EA0E")
        XCTAssert(errors != nil, "EA0E expected")

        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2025|1|K901|12718100||1234567890||2.22|50|Stück|A07AA01"]))
        try context.execute()
        errors = context.errorsWith (code:"EA05")
        XCTAssert(errors != nil, "EA05 expected")

        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2025|1|K901|12718100|XY|1234567890|Test1||50|Stück|A07AA01"]))
        try context.execute()
        errors = context.errorsWith (code:"EA06")
        XCTAssert(errors != nil, "EA06 expected")
        errors = context.errorsWith (code:"EA09")
        XCTAssert(errors != nil, "EA09 expected")

        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                        ["A01|2025|1|K901|12718100|DE|1234567890|Test1|2,22|50|Stück|A07AA10"]))
        try context.execute()
        errors = context.errorsWith (code:"EA06")
        XCTAssert(errors == nil, "EA06 not expected")
        errors = context.errorsWith (code:"EA0A")
        XCTAssert(errors == nil, "EA0A not expected")

        
        
        context = try createContextWith(model: minYear, year: 2025, lines: combine(lkfcSatzartA.fall1,
                                                                            ["A01|2025|1|K901|12718100|DE|1234567890|Test1|2,22|50|Stk|ATC1"]))
        try context.execute()
        errors = context.errorsWith (code:"EA0D")
        XCTAssert(errors != nil, "EA0D expected")
        errors = context.errorsWith (code:"EA0E")
        XCTAssert(errors != nil, "EA0E expected")
        
        let einheitOK = combine(lkfcSatzartA.fall1,
                                ["A01|2025|1|K901|12718100|DE|1234567890|Test1|2,22|50|Stück|A07AA10"])
        context = try createContextWith(model: minYear, year: 2025, lines: einheitOK)
        try context.execute()
        errors = context.errorsWith (code:"EA09")
        XCTAssert(errors == nil, "EA09 not expected")
        
        context = try lkfcSatzartA.createContextWith(model: minYear, year: 2025, cp1252Lines: einheitOK)
        try context.execute()
        errors = context.errorsWith (code:"EA09")
        XCTAssert(errors == nil, "EA09 not expected")
    }
}
