//
//  lkfcSpezBereichTests.swift
//  lkfcTests
//
//  Created by Alexander Holzer on 23.02.21.
//  Copyright © 2021 Alexander Holzer. All rights reserved.
//

import XCTest
@testable import lkfc

class lkfcSpezBereichTests: XCTestCase {

    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.
    }
    
    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)
    }

    
    static var fall_testGTK1 = [
        "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|16113601|20190401|0859|||||||N|10|",
        "X03|K534|234||20190401|G40.0|H|||",
        "X04|K534|234||20190401|AM090||J|1|20190401|1030|187867||",
        "L01|2019|K534|16113601|G|TK|",
    ]
    
    static var fall_testGTK2 = [
        "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|14113601|20190401|0859|||||||N|10|",
        "X03|K534|234||20190401|G40.0|H|||",
        "X04|K534|234||20190401|AK510||J|1|20190401|1030|187867||",
        "L01|2019|K534|14113601|G|TK|",
    ]

    static var fall_testGTKambulant = [
        "X01|K534|234||20190401|0859|I|20041105|10|M|AT|AT|5452|50416|1|P||||7|20190401|1355|17|J|4",
        "X02|K534|234||20190401|001|16113601|20190401|0859|J||||||N|10|",
        "X03|K534|234||20190401|G40.0|H|||",
        "X04|K534|234||20190401|AM090||J|1|20190401|1030|187867||",
        "L01|2019|K534|16113601|G|TK|",
    ]

    static var fall_testGTKambulant2 = [
        "X01|K534|234||20190401|0859|I|20041105|10|M|AT|AT|5452|50416|1|P||||7|20190401|1355|17|J|4",
        "X02|K534|234||20190401|001|14113601|20190401|0859|J||||||N|10|",
        "X03|K534|234||20190401|G40.0|H|||",
        "X04|K534|234||20190401|AM090||J|1|20190401|1030|187867||",
        "L01|2019|K534|14113601|G|TK|",
    ]
    
    func testGTK() throws {
        var context = try createContextWith(model:2020, lines: lkfcSpezBereichTests.fall_testGTK1)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        _ = resultForContext(context: context)
        var errors = context.errorsWith (code:"WX3A")
        XCTAssert (errors != nil, "warning WX3A expected") // FC für SpezBereich ungültig

        context = try createContextWith(model:2021, lines: lkfcSpezBereichTests.fall_testGTK1)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        _ = resultForContext(context: context)
        errors = context.errorsWith (code:"WX3A")
        XCTAssert (errors == nil, "warning WX3A not expected") // FC für SpezBereich ungültig
        
        context = try createContextWith(model:2020, lines: lkfcSpezBereichTests.fall_testGTK2)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        var result = resultForContext(context: context)
        XCTAssert(result == "X05|K534|234||20190401|HDG01.12|D|139|1200|||||||1339", "result differs")
        errors = context.errorsWith (code:"WX3A")
        XCTAssert (errors == nil, "warning WX3A not expected") // FC für SpezBereich ungültig

        context = try createContextWith(model:2021, lines: lkfcSpezBereichTests.fall_testGTK2)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        _ = resultForContext(context: context)
        errors = context.errorsWith (code:"WX3A")
        XCTAssert (errors != nil, "warning WX3A not expected") // FC für SpezBereich ungültig

        context = try createContextWith(model:2020, lines: lkfcSpezBereichTests.fall_testGTKambulant)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        result = resultForContext(context: context)
        XCTAssert(result == "X05|K534|234||20190401|AMG20.11|A|215||||||||215", "result differs")

        context = try createContextWith(model:2021, lines: lkfcSpezBereichTests.fall_testGTKambulant)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        result = resultForContext(context: context)
        XCTAssert(result == "X05|K534|234||20190401|AMG20.11|A|215||||||||215", "result differs")

        context = try createContextWith(model:2021, lines: lkfcSpezBereichTests.fall_testGTKambulant2)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        result = resultForContext(context: context)
        errors = context.errorsWith(code: "EK83")
        XCTAssert(errors != nil, "EK83 expected") // ung. fuer G-TK

        //let errors = context.errorsWith (code:"FATG") // X02 fehlt
        //XCTAssert (errors != nil, "error FATG expected")
    }

    static var fall_testEX3D = [
        "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|14113601|20190401|0859|||||||N|10|",
        "X03|K534|234||20190401|G40.0|H|||",
      //  "X04|K534|234||20190401|AM050||J|1|20190401|1030|187867||",
        "L01|2019|K534|14113601|G|A|",
    ]

    static var fall_testWX3A = [
        "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|14123456|20190401|0859|||||||N|10|",
        "X03|K534|234||20190401|G40.0|H|||",
      //  "X04|K534|234||20190401|AM050||J|1|20190401|1030|187867||",
        "L01|2019|K534|14123456|G|A|",
    ]

    func testEX3D() throws {
        var context = try createContextWith(model:2020, lines: lkfcSpezBereichTests.fall_testEX3D)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        _ = resultForContext(context: context)
        var errors = context.errorsWith (code:"EX3D")
        XCTAssert (errors != nil, "warning EX3D expected") // FC für SpezBereich ungültig

        context = try createContextWith(model:2020, lines: lkfcSpezBereichTests.fall_testWX3A)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        _ = resultForContext(context: context)
        errors = context.errorsWith (code:"WX3A")
        XCTAssert (errors != nil, "warning WX3A expected") // FC für SpezBereich ungültig

        context = try createContextWith(model:2021, lines: lkfcSpezBereichTests.fall_testEX3D)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        _ = resultForContext(context: context)
        errors = context.errorsWith (code:"WX3A")
        XCTAssert (errors != nil, "warning WX3A expected") // FC für SpezBereich ungültig

    }
    
    static var fall_L01 = [
        "L01|2021|K534|16123456|G|TK|", // 2020: ok,   2021: EK83 (beliebiger 16-Code nur bis 2020 erlaubt)
        "L01|2021|K534|14113601|G|TK|", // 2020: ok,   2021: EK83 (stat. GTK-Code nur bis 2020 erlaubt)
        "L01|2021|K534|16113601|G|TK|", // 2020: ok,   2021: ok   (amb. GTK-Code ab 2021, davor wegen beliebiger 16-Code auch ok)
        "L01|2021|K534|14006801|O|TK|", // 2020: ok,   2021: EK83 (stat. O-Code 14xx nur bis 2020 erlaubt)
        "L01|2021|K534|16006801|O|TK|", // 2020: ok,   2021: ok
        "L01|2021|K534|14016801|O|01|", // 2020: ok,   2021: ok   (stat. O-Code bei 01 weiterhin erlaubt)
        "L01|2021|K534|14620001|J|E|",  // 2020: ok,   2021: ok   (1x62 für J/E erlaubt)
        "L01|2021|K534|16626801|J|A|",  // 2020: ok,   2021: EK83 (1x62 nur für J/A, aber 2020 weil alle 16xx ok)
        "L01|2021|K534|14620002|J|01|", // 2020: EK83, 2021: EK83 (1x62 nur für J/E)
        "L01|2021|K534|14016802|P|01|", // 2020: ok,   2021: EK83 (Bereiche 01-03 gibt es nicht mehr)
        "L01|2021|K534|14620003|P|TS|", // 2020: ok,   2021: EK83 (ab 2021 nur ambulant)
        "L01|2021|K534|16620003|P|TS|", // 2020: ok,   2021: ok
        "L01|2021|K534|13913701|L|01|", // 2020: ok,   2021: ok
        "L01|2021|K534|13513702|L|01|"  // 2020: EK83, 2021: ok
    ]

    func testEK83() throws {
        var context = try createContextWith(model:2020, lines: lkfcSpezBereichTests.fall_L01)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        _ = resultForContext(context: context)
        var errors = context.errorsWith (code:"EK83")
        if let e = errors {
            XCTAssert(e.count == 2, "count of EK83 errors differs (\(e.count))")
        }
        else {
            XCTAssert(false, "EK83 not expected")
        }

        context = try createContextWith(model:2021, lines: lkfcSpezBereichTests.fall_L01)
        XCTAssert (context.lastError == nil, "couldn't not execute case" + context.lastError!.message)
        _ = resultForContext(context: context)
        errors = context.errorsWith (code:"EK83", errorTypes:255)

        if let e = errors {
            XCTAssert(e.count == 7, "count of EK83 errors differs (\(e.count))")
        }
        else {
            XCTAssert(false, "EK83 not expected")
        }
    }
}
