//
//  lkfc2019Tests.swift
//  lkfcTests
//
//  Created by Alexander Holzer on 09.08.18.
//  Copyright © 2018 Alexander Holzer. All rights reserved.
//

import XCTest
@testable import lkfc

class lkfc2019Tests: XCTestCase {
    
    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }
    
    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }
    
    
    static var fall_bg020 = [
        "X01|K714|1234||20190621|1200|S|19360501|80|M|AT|AT|1010|90101|A|P||||E|20190621|1200|11|J|0",
        "X02|K714|1234||20190621|01|11111100|20190621||J||||||N|80|",
        "X03|K714|1234||20190621|I51.9|H|D||",
        "X03|K714|1234||20190621|R53|Z|D||",
        "X04|K714|1234||20190621|BG020||J|0001|20190621|2024|18111600|"]
    
    static var fall_tirol1 = [
        "X01|K714|1234||20190621|1200|S|19360501|80|M|AT|AT|1010|90101|A|P||||E|20190621|1200|11|J|0",
        "X02|K714|1234||20190621|01|11111100|20190621||J||||||N|80|",
        "X03|K714|1234||20190621|I51.9|H|D||",
        "X03|K714|1234||20190621|R53|Z|D||",
        "X04|K714|1234||20190621|TI001||J|0001|20190621|2024|18111600|"]
    
    static var fall_tirol2 = [
        "X01|K714|1234||20190621|1200|I|19360501|80|M|AT|AT|1010|90101|1|P||||1|20190621|1200|11|J|0",
        "X02|K714|1234||20190621|01|16111100|20190621||J||||||N|80|",
        "X03|K714|1234||20190621|I51.9|H|D||",
        "X03|K714|1234||20190621|R53|Z|D||",
        "X04|K714|1234||20190621|TI001||J|0001|20190621|2024|18111600|"]
    
    static var fall_halbstatAmb = [
        "X01|K219|A01||20170118|0829|I|19410314|80|M|AT|AT|9462|20901|||||||||16|J|4||",
        "X02|K219|A01||20170118|001|18226700|20170118|0829|J||||||N|80|1712015740",
        "X02|K219|A01||20170118|002|16113601|20170118|1518|J||||||N|80|1712015740",
        "X03|K219|A01||20170118|I25.5|H|||1712015740",
        "X03|K219|A01||20170118|I48.9|Z|||1712015740",
        "X03|K219|A01||20170118|I69.3|Z|||1712015740",
        "X03|K219|A01||20170118|Z92.1|Z|||1712015740",
        "X03|K219|A01||20170118|Z95.0|Z|||1712015740",
        "X03|K219|A01||20170118|Z98.8|Z|||1712015740",
        "X04|K219|A01||20170118|AM090||J|1|20170118|1526|16113601||1712015740",
    ]
    
    static var fall_halbstatStat = [
        "X01|K219|A02||20170120|1042|S|19410314|80|M|AT|AT|9462|20901|H|A||||H|20170121|1435|16|J|4||",
        "X02|K219|A02||20170120|001|14113600|20170120|1042|J||||||N|80|1712015740",
        "X03|K219|A02||20170120|I25.5|H|||1712015740",
        "X03|K219|A02||20170120|I48.9|Z|||1712015740",
        "X03|K219|A02||20170120|I69.3|Z|||1712015740",
        "X03|K219|A02||20170120|Z92.1|Z|||1712015740",
        "X03|K219|A02||20170120|Z95.0|Z|||1712015740",
        "X03|K219|A02||20170120|Z98.8|Z|||1712015740",
        "X04|K219|A02||20170120|AM090||J|1|20170120|1552|16113601||1712015740",
        "X04|K219|A02||20170120|PE510||J|1|20170120|1401|18226700||1712015740",
        "X04|K219|A02||20170120|ZN840||J|1|20170120|1053|18226700||1712015740",
        "X04|K219|A02||20170120|ZZ531||J|1|20170120|1042|18226700||1712015740"
    ]
    
    static var fall_i61 = [
        "X01|K201|123||20190123|1947|S|19270516|85|W|AT|AT|9330|20501|A|A||||E|20190227|1139|16|J|0",
        "X02|K201|123||20190123|001|11638100|20190123|1947||20190201|1449|1|||N|85|",
        "X02|K201|123||20190123|002|11111100|20190201|1450||20190210|1505||||N|85|",
        "X02|K201|123||20190123|003|13113600|20190210|1506||20190227|1139||||N|85|",
        "X03|K201|123||20190123|I61.3|H|D||",
        "X04|K201|123||20190123|DE510||J|1|20190201|1547|16111100||",
        "X04|K201|123||20190123|DE510||J|1|20190220|0743|16111100||",
        "X04|K201|123||20190123|PE510||J|1|20190220|1030|187867||",
        "I11|K201|123||20190123|001|20190123|00|0|2|0|0|0|0|0|5|0|0|0|2|6,3|7,41|430|0|3|5|4|4|100|000000000000000000001|37,0|0|70,0|40|0,8|0,7|160|000|2",
        "I12|K201|123||20190123|001|20190123|1|1|2|1|0|0|1|0|1|1|0|1|0|0|0|0|1|0|0|0|0|0|1|1|4|0|0|0|0|0",
        "I12|K201|123||20190123|001|20190124|1|1|2|1|0|0|1|0|1|1|0|1|0|0|0|0|1|0|0|0|0|0|1|1|4|0|0|0|0|0",
        "I12|K201|123||20190123|001|20190125|1|1|2|1|0|0|1|0|1|1|0|1|0|0|0|0|1|0|0|0|0|0|0|0|4|0|0|0|0|0"
    ]
    
    static var fall_i61add1 = [
        "X03|K201|123||20190123|204.0|Z|D||"
    ]
    
    static var fall_i61add2 = [
        "X03|K201|123||20190123|201.1|Z|D||",
        "X03|K201|123||20190123|202.0|Z|D||",
        "X03|K201|123||20190123|203.1|Z|D||"
    ]
    
    static var fall_i61add3 = [
        "X03|K201|123||20190123|201.1|Z|D||",
        "X03|K201|123||20190123|202.0|Z|D||"
    ]
    
    func createContextWith (model: UInt32, year: Int32, lines : [String]) throws -> LKFContext {
        return try lkfcTests.createContextWith(model: model, year:year, lines: lines)
    }
    func createContextWith (provider: LKFContextStammProvider, model: UInt32, year: Int32, lines: [String]) throws -> LKFContext {
        return try lkfcTests.createContextWith (provider:provider, model:model, year:year, lines:lines)
    }
    
    func createContextWith (model: UInt32, lines : [String]) throws -> LKFContext {
        return try lkfcTests.createContextWith(model:model, lines:lines)
    }
    
    func resultForContext (context: LKFContext) -> String {
        return lkfcTests.resultForContext (context: context)
    }
    
    func combine (_ first:[String], _ second:[String]) -> [String] {
        return lkfcTests.combine(first, second)
    }
    
    func testBG020() throws {
        let context = try createContextWith(model:2019, lines: lkfc2019Tests.fall_bg020)
        XCTAssert (context.lastError == nil, "couln not execute case" + context.lastError!.message)
        let s = resultForContext(context: context)
        XCTAssert (s.compare("X05|K714|1234||20190621|HDG06.04|A|||36|30|||||66") == ComparisonResult.orderedSame, "result different")
    }
    
    func testTirol() throws {
        LKFContext.unloadStamm()
        let stammProvider = LKFContextStammProvider()
        stammProvider.add (file:"mellist.dat", line:"TI001                  M        2  3  2  3  NJTirol Special                                                                                       MELJ               2  3J          12000")
        var context = try createContextWith (provider:stammProvider, model: 2019, year:2019, lines:lkfc2019Tests.fall_tirol1)
        XCTAssert (context.lastError == nil, "couln not execute case: " + context.lastError!.message)
        var res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K714|1234||20190621|FEHLER||||||||||") == ComparisonResult.orderedSame, "result different")
        
        let ex4lErrors = context.errorsWith (code:"EX4L")
        XCTAssert (ex4lErrors != nil, "missing error")
        
        LKFContext.unloadStamm()
        
        context = try createContextWith (provider:stammProvider, model: 2019, year: 2019, lines:lkfc2019Tests.fall_tirol2)
        XCTAssert (context.lastError == nil, "couln not execute case: " + context.lastError!.message)
        res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K714|1234||20190621|APG00.00|C||25||||||12000|12025") == ComparisonResult.orderedSame, "result different")
        
        context = try createContextWith (model: 2018, year: 2019, lines:lkfc2019Tests.fall_tirol1)
        XCTAssert (context.lastError == nil, "couln not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K714|1234||20190621|FEHLER||||||||||") == ComparisonResult.orderedSame, "result different")
    }
    
    static var fall_tirol2025 = [
        "X01|K731|10000||20250119|0853|I|19840107|40|W|AT|AT|6321|70502|||||||||07|J|0",
        "X02|K731|10000||20250119|001|16915800|20250119|0000|J||||||N|40|",
        "X02|K731|10000||20250119|002|17821100|20250119|0000|J||||||N|40|",
        "X03|K731|10000||20250119|C50.9|H|||",
        "X04|K731|10000||20250119|XC768||J|1|20250119|0000|16915800||",
        "X04|K731|10000||20250119|Y7640||J|1|20250119|0000|17821100||",
        "X04|K731|10000||20250119|ZX840||J|1|20250119|0000|17821100||"
        ]
    
    func testTirol2025() throws {
        LKFContext.unloadStamm()
        let stammProvider = LKFContextStammProvider()
        stammProvider.add (file:"mellist.dat", line:"Y7640ZXVQF                                    Laboranalysen Kategorie 11 (LE=andere)                                                              KAL                3  4 JJ          1185")
        var context = try createContextWith (provider:stammProvider, model: 2025, year:2025, lines:lkfc2019Tests.fall_tirol2025)
        
        let res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K731|10000||20250119|MEL22.02|A|||463|275|||3|1185|1926") == ComparisonResult.orderedSame, "result different")

        let aufenthalt = context[0]
        
        let sum = aufenthalt.result.sum
        let lp = aufenthalt.result.sculk + aufenthalt.result.spez + aufenthalt.result.melzu
        
        var abtLP : Double = 0.0
        var abtTP : Double = 0.0
        for i in 0..<aufenthalt.abtCount {
            let scoringData = aufenthalt.abtAt(index: i).scoringData()
            abtLP += scoringData.lp
            abtTP += scoringData.tp
        }

        XCTAssert (Double(lp) == abtLP, "sum lp \(lp) different than abt sum \(abtLP)")
        XCTAssert (Double(sum) == abtLP + abtTP, "sum \(sum) different than abt sum (\(abtLP) + \(abtTP))")
        
    }
    
    func analyseAufenthalt(aufenthalt:LKFAufenthalt, prefix: String) {
        let abtCount = aufenthalt.abtCount
        
        var tp = 0.0
        var lp = 0.0
        var sum = 0.0
        
        for i in 0..<abtCount {
            let abt = aufenthalt.abtAt(index: i)
            let res = abt.scoringData()
            tp += res.tp
            lp += res.lp
            sum += res.sum
        }
        
        let result = aufenthalt.getResult()
        XCTAssert(Double(result.lp + result.spez) == lp, "\(prefix): Diff: Abt-LP \(result.lp + result.spez) vs \(lp)")
        XCTAssert(Double(result.tp) == tp, "\(prefix): Diff: Abt-KP \(result.tp) vs \(tp)")
        XCTAssert(Double(result.sum) == sum, "\(prefix): Diff: Abt-Sum \(result.sum) vs \(sum)")

        let melCount = aufenthalt.melCount

        var leist = 0
        
        for i in 0..<melCount {
            let mel = aufenthalt.melAt(index: i)
            let res = mel.scoringData()
            leist += res.leist
        }
        
        XCTAssert(result.lp + result.spez == leist, "\(prefix): Diff: MEL-LP \(result.lp + result.spez) vs \(leist)")
    }
    
    static var fall_melminimum = [
        "X01|K706|012||20190102|0712|I|20050725|10|M|AT|AT|6170|70369|||||||||40|J|0||",
        "X02|K706|012||20190102|001|16221100|20190102|0712|J||||||N|10|3008298036",
        "X02|K706|012||20190102|002|17225100|20190102|0750|J||||||N|10|3008298036",
        "X04|K706|012||20190102|ZD510||J|1|20190102|0800|17225100||3008298036"
    ]

    
    func testMELPointsMinimum() throws {
        let context = try createContextWith (model:2019, lines:lkfc2019Tests.fall_melminimum)
        try context.execute()
        let aufenthalt = context.first
        analyseAufenthalt(aufenthalt: aufenthalt, prefix:"testMELPointsMinimum")

    }
    
    static var fall_tirol2Minimum = [
        "X01|K706|30||20190214|0805|I|20130329|5|W|AT|AT|6091|70312|||||||||18|J|0||",
        "X02|K706|30||20190214|001|16517100|20190214|0805|J||||||N|5|3008306015",
        "X02|K706|30||20190214|002|17821100|20190214|0814|J||||||N|5|3008306015",
        "X04|K706|30||20190214|Y7610||J|1|20190214|0814|17821100||3008306015",
        "X04|K706|30||20190214|ZV510||J|1|20190214|0805|16517100||3008306015",
        "X04|K706|30||20190214|ZX670||J|1|20190214|0814|17821100||3008306015",
        "X07|K706|30||20190214|||||2203081262|"
    ]
    
    func testTirolMinimum() throws {
        let stammProvider = LKFContextStammProvider()
        stammProvider.add (file:"mellist.dat", line:"Y7610                           2  3  2  3  NJTirol Special                                                                                       MELJ               2  3N             30")
        let context = try createContextWith (provider:stammProvider, model: 2019, year:2019, lines:lkfc2019Tests.fall_tirol2Minimum)
        try context.execute()
        let aufenthalt = context.first
        analyseAufenthalt(aufenthalt: aufenthalt, prefix:"testTirolMinimum")

    }
    
    func testHalbstat () throws {
        var context = try createContextWith (model: 2018, year: 2017, lines:lkfc2019Tests.fall_halbstatStat)
        XCTAssert (context.lastError == nil, "couln not execute case" + context.lastError!.message)
        var res = resultForContext(context: context)
        var errors = context.errorsWith (code:"EX2D") // aufnahmeart für ABTFC ungültig
        XCTAssert (errors != nil, "missing error")
        errors = context.errorsWith (code:"EX26") // leistung ohne FUCO
        XCTAssert (errors != nil, "missing error")

        context = try createContextWith (model: 2019, year: 2017, lines:lkfc2019Tests.fall_halbstatStat)
        XCTAssert (context.lastError == nil, "couln not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        errors = context.errorsWith (code:"EX2C") // aufnahmeart ungültig
        XCTAssert (errors != nil, "missing error")
        errors = context.errorsWith (code:"EX2D") // aufnahmeart komb fuco weg
        XCTAssert (errors == nil, "missing error")
        errors = context.errorsWith (code:"EX0F") // entart ungueltig
        XCTAssert (errors != nil, "missing error")

        // let result = context.first.getResult()
        
        LKFContext.unloadStamm()
        var stammProvider = LKFContextStammProvider()
        stammProvider.add (file:"SPEZLIST.dat", line:"G2017K21914113600          TK")
        context = try createContextWith (provider:stammProvider, model: 2018, year: 2017, lines:lkfc2019Tests.fall_halbstatStat)
        res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K219|A02||20170120|MEL31.01|A|215||||||||215") == ComparisonResult.orderedSame, "result different")

        LKFContext.unloadStamm()
        
        // TODO: check errors
        
        stammProvider = LKFContextStammProvider()
        stammProvider.add (file:"SPEZLIST.dat", line:"G2017K21916113601          TK")
        
        context = try createContextWith (provider:stammProvider, model: 2018, year: 2017, lines:lkfc2019Tests.fall_halbstatAmb)
        XCTAssert (context.lastError == nil, "couln not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K219|A01||20170118|AMG20.11|A|215||||||||215") == ComparisonResult.orderedSame, "result different")
        
        context = try createContextWith (provider:stammProvider, model: 2019, year: 2017, lines:lkfc2019Tests.fall_halbstatAmb)
        XCTAssert (context.lastError == nil, "couln not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K219|A01||20170118|AMG20.11|A|215||||||||215") == ComparisonResult.orderedSame, "result different")
        LKFContext.unloadStamm()
    }
    
    static var fall_i61_zz723 = [
        "X04|K201|123||20190123|ZZ723||J|1|20190201|1547|16111100||",

    ]

    
    func testI61 () throws {
        
        let stammProvider = LKFContextStammProvider()
        //stammProvider.add (file:"SPEZLIST.dat", line:"S2018K20111638100")
        stammProvider.add (file:"DIAGLIST.dat", line:"201.1                                         Revisionsgrund: Implantatbruch ñ Femurkopf                                                                                                                                                                 Revisionsgrund: Implantatbruch ñ Femurkopf")
        stammProvider.add (file:"DIAGLIST.dat", line:"202.0                                         Revisionsgrund: Chondropathie ñ Femur (nach Halbschlitten)                                                                                                                                                 Revisionsgrund: Chondropathie ñ Femur (nach Halbschlitten)")
        stammProvider.add (file:"DIAGLIST.dat", line:"203.1                                         Revisionsgrund: Materialabrieb                                                                                                                                                                             Revisionsgrund: Materialabrieb")
        stammProvider.add (file:"DIAGLIST.dat", line:"204.0                                         Revisionsgrund: Luxation                                                                                                                                                                                   Revisionsgrund: Luxation")

        var context = try createContextWith (provider:stammProvider, model: 2018, year: 2019, lines:lkfc2019Tests.fall_i61)
        XCTAssert (context.lastError == nil, "could not execute case" + context.lastError!.message)
        var res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K201|123||20190123|HDG01.21|A|386|3153|||6778||||10317") == ComparisonResult.orderedSame, "result different")
        
        context = try createContextWith (provider:stammProvider, model: 2019, year: 2019, lines:lkfc2019Tests.fall_i61)
        XCTAssert (context.lastError == nil, "could not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        var errors = context.errorsWith (code:"EX4M") // rankin
        XCTAssert (errors != nil, "missing error")

        context = try createContextWith (provider:stammProvider, model: 2019, year: 2019, lines:combine (lkfc2019Tests.fall_i61, lkfc2019Tests.fall_i61add1))
        XCTAssert (context.lastError == nil, "could not not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K201|123||20190123|HDG01.21|A|386|3153|||6778||||10317") == ComparisonResult.orderedSame, "result different")
        
        context = try createContextWith (provider:stammProvider, model: 2019, year: 2019, lines:combine (lkfc2019Tests.fall_i61, lkfc2019Tests.fall_i61add2))
        XCTAssert (context.lastError == nil, "could not not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        XCTAssert (res.compare("X05|K201|123||20190123|HDG01.21|A|386|3153|||6778||||10317") == ComparisonResult.orderedSame, "result different")
        
        context = try createContextWith (provider:stammProvider, model: 2019, year: 2019, lines:combine (lkfc2019Tests.fall_i61, lkfc2019Tests.fall_i61add3))
        XCTAssert (context.lastError == nil, "could not not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        errors = context.errorsWith (code:"EX4M") // rankin
        XCTAssert (errors != nil, "missing error")
        
        let i61zz723 = combine (lkfc2019Tests.fall_i61, lkfc2019Tests.fall_i61_zz723)
        
        context = try createContextWith (provider:stammProvider, model: 2022, year: 2019, lines:i61zz723)
        XCTAssert (context.lastError == nil, "could not not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        errors = context.errorsWith (code:"EX4M") // rankin
        XCTAssert (errors != nil, "missing error")
        
        context = try createContextWith (provider:stammProvider, model: 2023, year: 2019, lines:i61zz723)
        XCTAssert (context.lastError == nil, "could not not execute case" + context.lastError!.message)
        res = resultForContext(context: context)
        errors = context.errorsWith (code:"EX4M") // rankin
        XCTAssert (errors == nil, "EX4M not expected with ZZ723")
        LKFContext.unloadStamm()
    }
    
    static var fall_aufartG = [
        "X01|K714|1234||20180101|1200|S|20171231|80|M|AT|AT|1010|90101|G|P||K901||E|20180201|1200|11|J|0",
        "X02|K714|1234||20180101|01|11111100|20180101||J||||||N|80|",
        "X03|K714|1234||20180101|I51.9|H|D||",
        "X03|K714|1234||20180101|R53|Z|D||"
    ]

    static var fall_aufartG2 = [
        "X01|K714|1234||20171231|1200|S|20171231|80|M|AT|AT|1010|90101|T|P||K901||E|20180201|1200|11|J|0",
        "X02|K714|1234||20171231|01|11111100|20171231||J||||||N|80|",
        "X03|K714|1234||20171231|I51.9|H|D||",
        "X03|K714|1234||20171231|R53|Z|D||"
    ]
    
    static var fall_aufartG3 = [
        "X01|K714|1234||20180101|1200|S|20171231|80|M|AT|AT|1010|90101|T|P||K901||E|20180201|1200|11|J|0",
        "X02|K714|1234||20180101|01|11111100|20180101||J||||||N|80|",
        "X03|K714|1234||20180101|I51.9|H|D||",
        "X03|K714|1234||20180101|R53|Z|D||"
    ]

    func testAufartG () throws {
        var context = try createContextWith (model: 2019, year: 2018, lines:lkfc2019Tests.fall_aufartG)
        try context.execute()
        var res = context.first.getResult()
        let sumPoints = res.sum
        XCTAssert (sumPoints > 0, "no points")

        context = try createContextWith (model: 2019, year: 2018, lines:lkfc2019Tests.fall_aufartG2)
        try context.execute()
        res = context.first.getResult()
        let sumPoints2 = res.sum
        XCTAssert (sumPoints2 > 0, "no points")
        
        context = try createContextWith (model: 2019, year: 2018, lines:lkfc2019Tests.fall_aufartG3)
        try context.execute()
        res = context.first.getResult()
        let errors = context.errorsWith (code:"EX4K") // AUFART-Alter
        XCTAssert (errors != nil, "missing error")
    }

    static var fall_testL01 = [
        "X01|K534|234||20190401|0859|S|20041105|10|M|AT|AT|5452|50416|A|P||||E|20190402|0955|17|J|4",
        "X02|K534|234||20190401|001|14628500|20190401|0859|||||||N|10|",
        "X03|K534|234||20190401|G40.0|H|||",
        "X04|K534|234||20190401|AM060||J|1|20190401|1030|187867||",
        "L01|2019|K534|12345678|P|TK|",
        "L01|2019|K534|14628500|P|TK|",
        "L01|2019|K534|14628500|P|TS|",
        "L01|2019|K534|12718100|I|E3|1664",
        "L01|2019|K534|12718100|I|E1|964",
        "L01|2019|K534|12718101|I|E0|480",
        "L01|2019|K534||M|01|",
        "L01|2019|K534||M|01|",
        "L01|2019|K901||M|02|",
        "L01|2019|K901||M|02|",
        "L01|2019|K534||M|02|"
    ]

    static var fall_testL02 = [
        "X01|K534|234||20190401|0859|S|20041105|10|M|AT|AT|5452|50416|A|P||||E|20190402|0955|17|J|4",
        "X02|K534|234||20190401|001|14628500|20190401|0859|||||||N|10|",
        "X03|K534|234||20190401|G40.0|H|||",
        "X04|K534|234||20190401|AM080||J|1|20190401|1030|187867||",
        "L01|2019|K534|12345678|P|TK|",
        "L01|2019|K534|14628500|P|TS|",
        "L01|2019|K534|14628500|P|TK|",
        "L01|2019|K534|12718100|I|E3|1664",
        "L01|2019|K534|12718100|I|E1|964",
        "L01|2019|K534|12718101|I|E0|480",
        "L01|2019|K534||M|01|",
        "L01|2019|K534||M|02|"
    ]

    func testL01 () throws {
        var context = try createContextWith (model: 2019, year: 2019, lines:lkfc2019Tests.fall_testL01)
        try context.execute()
        var res = context.first.getResult()
        var errors = context.errorsWith (code:"FATT") // Abteilung mehrfach in L01
        XCTAssert (errors != nil && errors!.count == 2, "missing FATT errors")
        
        context = try createContextWith (model: 2019, year: 2019, lines:lkfc2019Tests.fall_testL02)
        try context.execute()
        res = context.first.getResult()
        //err = context.getErrors()
        XCTAssert (res.sum > 0, "no points")

        context = try createContextWith (model: 2023, year: 2019, lines:lkfc2019Tests.fall_testL01)
        try context.execute()
        res = context.first.getResult()
        errors = context.errorsWith (code:"FATT") // Abteilung mehrfach in L01
        XCTAssert (errors != nil && errors!.count == 2, "missing FATT errors")

        context = try createContextWith (model: 2024, year: 2019, lines:lkfc2019Tests.fall_testL01)
        try context.execute()
        res = context.first.getResult()
        errors = context.errorsWith (code:"FATT") // Abteilung mehrfach in L01
        XCTAssert (errors != nil && errors!.count == 4, "missing FATT errors")
    }
    
    static var fall_aa040 = [
        "X01|K534|123||20170701|0551|S|19401103|75|W|AT|AT|5620|50421|A|A|||P500|E|20170901|1214|17|J|2",
        "X02|K534|123||20170701|001|11638100|20170701|0551|||||||N|75|",
        "X03|K534|123||20170701|I63.9|H|||",
        "X03|K534|123||20170701|I10|Z|||",
        "X03|K534|123||20170701|I63.4|Z|||",
        "X03|K534|123||20170701|I65.0|Z|||",
        "X03|K534|123||20170701|I65.1|Z|||",
        "X03|K534|123||20170701|I66.2|Z|||",
        "X04|K534|123||20170701|AA040||J|1|20170701|0551|11638100||",
        "X04|K534|123||20170701|ZA010||J|1|20170701|0558|17721300||"
]
    
    func testAA040 () throws {
        let context = try createContextWith (model: 2018, year: 2017, lines:lkfc2019Tests.fall_aa040)
        try context.execute()
        //let res = context.first.getResult()
        let errors = context.errorsWith (code:"WX3Q") // AUFART-Alter
        XCTAssert (errors != nil, "missing WX3Q errors")
    }
    
    static var fall_zz710 = [
        "X01|K214|01||20190101|0120|I|19900101|25|M|AT|AT|9102|20817|||||||||16|J|0",
        "X02|K214|01||20190101|001|17821100|20190101|0120|J||||||N|25|",
        "X02|K214|01||20190101|002|16914400|20190101|0125|J||||||N|25|",
        "X02|K214|01||20190101|003|16111100|20190101|0138|J||||||N|25|",
        "X03|K214|01||20190101|R51|H|D||",
        "X03|K214|01||20190101|I10|Z|D||",
        "X04|K214|01||20190101|ZX540||J|7|20190101|0120|17821100||",
        "X04|K214|01||20190101|ZX580||J|14|20190101|0120|17821100||",
        "X04|K214|01||20190101|ZX620||J|1|20190101|0120|17821100||",
        "X04|K214|01||20190101|ZZ710||J|1|20190101|0125|16914400||",
        "X04|K214|01||20190101|ZZ710||J|1|20190101|0125|17821100||"
    ]
    
    func testZZ710 () throws {
        let context = try createContextWith (model: 2019, year: 2019, lines:lkfc2019Tests.fall_zz710)
        try context.execute()
        //let res = context.first.getResult()
        let errors = context.errorsWith (code:"EX4R") // AUFART-Alter
        XCTAssert (errors != nil && errors!.count == 1, "invalid count of EX4R")
    }
    
    
    static var fall_strokeUnit = [
    "X01|K999|079||20170101|1200|S|19360501|80|M|AT|AT|1010|90101|A|P||||E|20170104|1200|11|J|0",
    "X02|K999|079||20170101|001|11638100|20170101||||||||N|80|",
    "X03|K999|079||20170101|G40.0|H|||",
    "X03|K999|079||20170101|I60.0|Z|||",
    "X05|K999|079||20170101|MEL26.02|A|1335|4180|||||||5515",
    "L01|2017|K999|11638100|S|01|"
    ]
    
    static var fall_strokeAdd = [
        "X04|K999|079||20170101|AA040||J|1|20170101||11111100||"
    ];
    
    static var fall_strokeAdd2 = [
         "X03|K999|079||20170101|I61.0|Z|||",
    ];
    
    func testStrokeUnit () throws {
        var context = try createContextWith (model: 2018, year: 2017, lines:lkfc2019Tests.fall_strokeUnit)
        try context.execute()
        var res = resultForContext(context: context)
        // Stroke-Abteilung, keine Diagnose, keine MEL -> OK 2018
        XCTAssert (res.compare("X05|K999|079||20170101|HDG01.12|C|251|2096|||||||2347") == ComparisonResult.orderedSame, "result different")

        context = try createContextWith (model: 2019, year: 2017, lines:lkfc2019Tests.fall_strokeUnit)
        try context.execute()
        res = resultForContext(context: context)
        // Stroke-Abteilung, keine Diagnose, keine MEL -> OK 2019
        XCTAssert (res.compare("X05|K999|079||20170101|HDG01.12|C|251|2096|||||||2347") == ComparisonResult.orderedSame, "result different")
        
        context = try createContextWith (model: 2019, year: 2017, lines:combine (lkfc2019Tests.fall_strokeUnit, lkfc2019Tests.fall_strokeAdd))
        try context.execute()
        res = resultForContext(context: context)
         // Stroke-Abteilung, keine Diagnose, MEL -> OK 2019
        XCTAssert (res.compare("X05|K999|079||20170101|MEL26.02|A|1335|4180|||||||5515") == ComparisonResult.orderedSame, "result different")

        context = try createContextWith (model: 2018, year: 2017, lines:combine (lkfc2019Tests.fall_strokeUnit, lkfc2019Tests.fall_strokeAdd2))
        try context.execute()
        res = resultForContext(context: context)
         // Stroke-Abteilung, keine Diagnose, I61, keine MEL -> OK 2018
        XCTAssert (res.compare("X05|K999|079||20170101|HDG01.12|C|251|2096|||||||2347") == ComparisonResult.orderedSame, "result different")

        context = try createContextWith (model: 2019, year: 2017, lines:combine (lkfc2019Tests.fall_strokeUnit, lkfc2019Tests.fall_strokeAdd2))
        try context.execute()
        //res = resultForContext(context: context)
        // Stroke-Abteilung, keine Diagnose, I61, keine MEL -> EX4T
        res = resultForContext(context: context)
        // Stroke-Abteilung, keine Diagnose, I61, keine MEL -> OK 2019
        let errors = context.errorsWith (code:"EX4T") // AA040 fehlt
        XCTAssert (errors != nil, "missing EX4T")
    }
    
    static var fall_ambEX0Z = ["X01|K920|123||20170905|0834|I|20020501|45|M|AT|AT|1090|90601|||||||||08|K|3",
                               "X02|K920|123||20170905|001|16221100|20170905|0834|J||||||N|45|",
                               "X02|K920|123||20170905|002|16221100|20170908|0834|J||||||N|45|",
                               "X02|K920|123||20170905|003|16221100|20170918|0834|J||||||N|45|",
                               "X03|K920|123||20170905|T92.1|H|D||",
                               "X04|K920|123||20170905|PE520||J|1|20170905|0834|16221100||",
                               "X04|K920|123||20170905|PE520||J|1|20170905|0834|16221100||",
                               "X04|K920|123||20170905|ZD510||J|1|20170905|0905|16221100||",
                               "X04|K920|123||20170905|ZN740||J|1|20170905|0834|16221100||",
                               "X04|K920|123||20170905|ZZ670||J|1|20170905|0856|16221100||"];

    
    func testAmbEX0Z () throws  {
        var context = try createContextWith (model: 2017, year: 2017, lines:lkfc2019Tests.fall_ambEX0Z)
        try context.execute()
        var res = resultForContext(context: context)
        // Stroke-Abteilung, keine Diagnose, keine MEL -> OK 2018
        XCTAssert (res.compare("X05|K920|123||20170905|APG12.61|A|15|30|||||||45") == ComparisonResult.orderedSame, "result different")

        context = try createContextWith (model: 2018, year: 2017, lines:lkfc2019Tests.fall_ambEX0Z)
        try context.execute()
        res = resultForContext(context: context)
        // Stroke-Abteilung, keine Diagnose, keine MEL -> OK 2018
        XCTAssert (res.compare("X05|K920|123||20170905|FEHLER||||||||||") == ComparisonResult.orderedSame, "result different")
        let errors = context.errorsWith (code:"EX0Z") // zugang ausserhalb aufenthalt
        XCTAssert (errors != nil, "missing EX0Z")
    }
/*
    static var fall_strokeUnit2 = [
        "X01|K999|079||20170101|1200|S|19360501|80|M|AT|AT|1010|90101|A|P||||E|20170104|1200|11|J|0",
        "X02|K999|079||20170101|001|11638100|20170101||||||||N|80|",
        "X03|K999|079||20170101|G40.0|H|||",
        "X03|K999|079||20170101|I63.0|Z|||"
//        "X05|K999|079||20170101|MEL26.02|A|1335|4180|||||||5515",
//        ,"X04|K999|079||20170101|AA040||J|1|20170101||11111100||"
       ,"L01|2017|K999|11638100|S|01|"
    ]
    /*
    static var fall_strokeAdd = [
        "X04|K999|079||20170101|AA040||J|1|20170101||11111100||"
    ];
    
    static var fall_strokeAdd2 = [
        "X03|K999|079||20170101|I61.0|Z|||",
        ];
    */
    func testStrokeUnit2 () {
        let context = try createContextWith (model: 2019, year: 2017, lines:lkfc2019Tests.fall_strokeUnit2)
        try context.execute()
        let res = resultForContext(context: context)
        // Stroke-Abteilung, keine Diagnose, keine MEL -> OK 2018
        XCTAssert (res.compare("X05|K999|079||20170101|HDG01.12|C|251|2096|||||||2347") == ComparisonResult.orderedSame, "result different")
    }
 */
}
