//
/*
 * Copyright (c) 2022 BWI GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import XCTest
@testable import Element

final class ServerDownTimeTests: XCTestCase {

    private let typeMain = "MAINTENANCE"
    private let typeAdhoc = "ADHOC_MESSAGE"
    
    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 testWarningTimeMaintenance() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-2),
                          "start_time": isoDate(2),
                          "end_time": isoDate(4),
                          "type": typeMain,
                          "description": "",
                          "blocking": true]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .warning)
    }
    
    func testRunningMaintenance() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-4),
                          "start_time": isoDate(-2),
                          "end_time": isoDate(4),
                          "type": typeMain,
                          "description": "",
                          "blocking": true]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .ongoing)
    }
    
    func testRunningBlockingMaintenance() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-4),
                          "start_time": isoDate(-2),
                          "end_time": isoDate(4),
                          "type": typeMain,
                          "description": "",
                          "blocking": true]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .ongoing)
        XCTAssert(service.isBlocking())
    }
    
    func testRunningNoneBlockingMaintenance() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-4),
                          "start_time": isoDate(-2),
                          "end_time": isoDate(4),
                          "type": typeMain,
                          "description": "",
                          "blocking": false]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .ongoing)
        XCTAssert(service.isBlocking() == false)
    }
    
    func testRunningBlockingDefaultMaintenance() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-4),
                          "start_time": isoDate(-2),
                          "end_time": isoDate(4),
                          "type": typeMain,
                          "description": ""]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .ongoing)
        XCTAssert(service.isBlocking() == false)
    }
    
    func testAdhocMessage() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-4),
                          "start_time": isoDate(-2),
                          "end_time": isoDate(4),
                          "type": typeAdhoc,
                          "description": "Text"]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .ongoing)
        XCTAssert(service.downtimeText() == "Text")
    }
    
    func testAdhocMessageWithoutDescription() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-4),
                          "start_time": isoDate(-2),
                          "end_time": isoDate(4),
                          "type": typeAdhoc
                         ]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .none)
    }

    func testToBigWarningDate() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(2),
                          "start_time": isoDate(-2),
                          "end_time": isoDate(4),
                          "type": typeAdhoc,
                          "description": "Text"]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .none)
    }
    
    func testToBigStartDate() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-2),
                          "start_time": isoDate(4),
                          "end_time": isoDate(2),
                          "type": typeAdhoc,
                          "description": "Text"]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .none)
    }
    
    func testWrongType() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": isoDate(-4),
                          "start_time": isoDate(-2),
                          "end_time": isoDate(2),
                          "type": "TYPPP",
                          "description": "Text"]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .none)
    }
    
    func testDateFormatType() throws {
        let service = ServerDowntimeDefaultService()
        
        let downtimes = [["warning_start_time": "2023-0100:00:00",
                          "start_time": isoDate(-2),
                          "end_time": isoDate(2),
                          "type": typeMain,
                          "description": "Text"]]
        
        
        try service.loadDowntimes(downtimes: downtimes)
        
        XCTAssert(service.nextDowntimeStatus() == .none)
    }

    private func isoDate(_ hours: Int) -> String {
        let dateFormatter = ISO8601DateFormatter()
        return dateFormatter.string(from: Calendar.current.date(byAdding: .hour, value:hours, to: Date())!)
    }
}
