// 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

#if !(os(OSX) || os(iOS))
    import CoreFoundation
#endif


class TestThread : XCTestCase {
    static var allTests: [(String, (TestThread) -> () throws -> Void)] {
#if os(Android)
        return []
#endif
        return [
            ("test_currentThread", test_currentThread ),
            ("test_threadStart", test_threadStart),
            ("test_threadName", test_threadName),
            ("test_mainThread", test_mainThread),
            ("test_callStackSymbols", test_callStackSymbols),
            ("test_callStackReurnAddresses", test_callStackReturnAddresses),
        ]
    }

    func test_currentThread() {
        let thread1 = Thread.current
        let thread2 = Thread.current
        XCTAssertNotNil(thread1)
        XCTAssertNotNil(thread2)
        XCTAssertEqual(thread1, thread2)
        XCTAssertEqual(thread1, Thread.mainThread)
    }
    
    func test_threadStart() {
        let condition = NSCondition()
        condition.lock()

        let thread = Thread() {
            condition.lock()
            condition.broadcast()
            condition.unlock()
        }
        thread.start()

        let ok = condition.wait(until: Date(timeIntervalSinceNow: 10))
        condition.unlock()
        XCTAssertTrue(ok, "NSCondition wait timed out")
    }
    
    func test_threadName() {

        // Compare the name set in pthreads()
        func compareThreadName(to name: String) {
            var buf = [Int8](repeating: 0, count: 128)
#if os(OSX) || os(iOS)
            // Dont use _CF functions on macOS as it will break testing with Darwin's native Foundation.
            let r = pthread_getname_np(pthread_self(), &buf, buf.count)
#else
            let r = _CFThreadGetName(&buf, Int32(buf.count))
#endif
            if r == 0 {
                XCTAssertEqual(String(cString: buf), name)
            } else {
                XCTFail("Cant get thread name")
            }
        }

        // No name is set initially
        XCTAssertNil(Thread.current.name)

#if os(Linux) // Linux sets the initial thread name to the process name.
        compareThreadName(to: "TestFoundation")
#else
        compareThreadName(to: "")
#endif
        Thread.current.name = "mainThread"
        XCTAssertEqual(Thread.mainThread.name, "mainThread")

        let condition = NSCondition()
        condition.lock()

        let thread2 = Thread() {
            XCTAssertEqual(Thread.current.name, "Thread2-1")
            compareThreadName(to: "Thread2-1")

            Thread.current.name = "Thread2-2"
            XCTAssertEqual(Thread.current.name, "Thread2-2")
            compareThreadName(to: "Thread2-2")

            Thread.current.name = "12345678901234567890"
            XCTAssertEqual(Thread.current.name, "12345678901234567890")
#if os(OSX) || os(iOS)
            compareThreadName(to: "12345678901234567890")
#elseif os(Linux)
            // pthread_setname_np() only allows 15 characters on Linux, so setting it fails
            // and the previous name will still be there.
            compareThreadName(to: "Thread2-2")
#endif
            condition.lock()
            condition.signal()
            condition.unlock()
        }
        thread2.name = "Thread2-1"
        thread2.start()

        // Allow 1 second for thread2 to finish
        XCTAssertTrue(condition.wait(until: Date(timeIntervalSinceNow: 1)))
        condition.unlock()

        XCTAssertEqual(Thread.current.name, "mainThread")
        XCTAssertEqual(Thread.mainThread.name, "mainThread")
        let thread3 = Thread()
        thread3.name = "Thread3"
        XCTAssertEqual(thread3.name, "Thread3")
    }

    func test_mainThread() {
        XCTAssertTrue(Thread.isMainThread)
        let t = Thread.mainThread
        XCTAssertTrue(t.isMainThread)
        let c = Thread.current
        XCTAssertTrue(c.isMainThread)
        XCTAssertTrue(c.isExecuting)
        XCTAssertTrue(c.isEqual(t))

        let condition = NSCondition()
        condition.lock()

        let thread = Thread() {
            condition.lock()
            XCTAssertFalse(Thread.isMainThread)
            XCTAssertFalse(Thread.mainThread == Thread.current)
            condition.broadcast()
            condition.unlock()
        }
        thread.start()

        let ok = condition.wait(until: Date(timeIntervalSinceNow: 10))
        condition.unlock()
        XCTAssertTrue(ok, "NSCondition wait timed out")
    }

    func test_callStackSymbols() {
        let symbols = Thread.callStackSymbols
        XCTAssertTrue(symbols.count > 0)
        XCTAssertTrue(symbols.count <= 128)
    }

    func test_callStackReturnAddresses() {
        let addresses = Thread.callStackReturnAddresses
        XCTAssertTrue(addresses.count > 0)
        XCTAssertTrue(addresses.count <= 128)
    }
}
