// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//


#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
    import Foundation
    import XCTest
#else
    import SwiftFoundation
    import SwiftXCTest
#endif


class TestNSTimer : XCTestCase {
    static var allTests : [(String, (TestNSTimer) -> () throws -> Void)] {
        return [
            ("test_timerInit", test_timerInit),
            ("test_timerTickOnce", test_timerTickOnce),
            ("test_timerRepeats", test_timerRepeats),
            ("test_timerInvalidate", test_timerInvalidate),
        ]
    }
    
    func test_timerInit() {
        let timer = NSTimer(fireDate: NSDate(), interval: 0.3, repeats: false) { _ in }
        XCTAssertNotNil(timer)
    }
    
    func test_timerTickOnce() {
        var flag = false
        
        let dummyTimer = NSTimer.scheduledTimer(0.01, repeats: false) { timer in
            XCTAssertFalse(flag)

            flag = true
            timer.invalidate()
        }

        let runLoop = NSRunLoop.currentRunLoop()
        runLoop.addTimer(dummyTimer, forMode: NSDefaultRunLoopMode)
        runLoop.runUntilDate(NSDate(timeIntervalSinceNow: 0.05))
        
        XCTAssertTrue(flag)
    }

    func test_timerRepeats() {
        var flag = 0
        let interval = NSTimeInterval(0.1)
        let numberOfRepeats = 3
        var previousInterval = NSDate().timeIntervalSince1970
        
        let dummyTimer = NSTimer.scheduledTimer(interval, repeats: true) { timer in
            XCTAssertEqual(timer.timeInterval, interval)

            let currentInterval = NSDate().timeIntervalSince1970
            XCTAssertEqualWithAccuracy(currentInterval, previousInterval + interval, accuracy: 0.01)
            previousInterval = currentInterval
            
            flag += 1
            if (flag == numberOfRepeats) {
                timer.invalidate()
            }
        }
        
        let runLoop = NSRunLoop.currentRunLoop()
        runLoop.addTimer(dummyTimer, forMode: NSDefaultRunLoopMode)
        runLoop.runUntilDate(NSDate(timeIntervalSinceNow: interval * Double(numberOfRepeats + 1)))
        
        XCTAssertEqual(flag, numberOfRepeats)
    }

    func test_timerInvalidate() {
        var flag = false
        
        let dummyTimer = NSTimer.scheduledTimer(0.01, repeats: true) { timer in
            XCTAssertTrue(timer.valid)
            XCTAssertFalse(flag) // timer should tick only once
            
            flag = true
            
            timer.invalidate()
            XCTAssertFalse(timer.valid)
        }
        
        let runLoop = NSRunLoop.currentRunLoop()
        runLoop.addTimer(dummyTimer, forMode: NSDefaultRunLoopMode)
        runLoop.runUntilDate(NSDate(timeIntervalSinceNow: 0.05))
        
        XCTAssertTrue(flag)
    }

}
