import Foundation
from PyObjCTools.TestSupport import TestCase, min_os_level
import objc


class TestNSObjCRuntime(TestCase):
    def test_typed_enum(self):
        self.assertIsTypedEnum(Foundation.NSExceptionName, str)
        self.assertIsTypedEnum(Foundation.NSRunLoopMode, str)

    def test_enum_types(self):
        self.assertIsEnumType(Foundation.NSComparisonResult)
        self.assertIsEnumType(Foundation.NSEnumerationOptions)
        self.assertIsEnumType(Foundation.NSQualityOfService)
        self.assertIsEnumType(Foundation.NSSortOptions)

    def testConstants(self):
        self.assertEqual(Foundation.NSQualityOfServiceUserInteractive, 0x21)
        self.assertEqual(Foundation.NSQualityOfServiceUserInitiated, 0x19)
        self.assertEqual(Foundation.NSQualityOfServiceUtility, 0x11)
        self.assertEqual(Foundation.NSQualityOfServiceBackground, 0x09)
        self.assertEqual(Foundation.NSQualityOfServiceDefault, -1)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_0, 397.40)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_1, 425.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_1_1, 425.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_1_2, 425.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_1_3, 425.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_1_4, 425.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2, 462.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2_1, 462.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2_2, 462.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2_3, 462.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2_4, 462.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2_5, 462.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2_6, 462.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2_7, 462.70)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_2_8, 462.70)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3, 500.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_1, 500.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_2, 500.30)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_3, 500.54)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_4, 500.56)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_5, 500.56)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_6, 500.56)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_7, 500.56)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_8, 500.56)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_3_9, 500.58)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4, 567.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_1, 567.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_2, 567.12)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_3, 567.21)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_4_Intel, 567.23)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_4_PowerPC, 567.21)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_5, 567.25)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_6, 567.26)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_7, 567.27)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_8, 567.28)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_9, 567.29)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_10, 567.29)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_4_11, 567.36)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5, 677.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_1, 677.10)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_2, 677.15)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_3, 677.19)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_4, 677.19)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_5, 677.21)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_6, 677.22)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_7, 677.24)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_8, 677.26)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6, 751.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6_1, 751.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6_2, 751.14)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6_3, 751.21)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6_4, 751.29)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6_5, 751.42)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6_6, 751.53)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6_7, 751.53)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_6_8, 751.62)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_8, 945.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_8_1, 945.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_8_2, 945.11)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_8_3, 945.16)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_8_4, 945.18)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_9, 1056)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_9_1, 1056)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_9_2, 1056.13)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_10, 1151.16)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_10_1, 1151.16)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_10_2, 1152.14)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_10_3, 1153.20)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_10_4, 1153.20)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_10_5, 1154)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_10_Max, 1199)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_11, 1252)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_11_1, 1255.1)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_11_2, 1256.1)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_11_3, 1256.1)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_11_4, 1258)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_11_Max, 1299)

        self.assertIsInstance(Foundation.NSFoundationVersionNumber, float)
        self.assertIsInstance(Foundation.NSIntegerMax, int)
        self.assertIsInstance(Foundation.NSIntegerMin, int)
        self.assertIsInstance(Foundation.NSUIntegerMax, int)
        self.assertEqual(Foundation.NSIntegerMax, 2**63 - 1)
        self.assertEqual(Foundation.NSIntegerMin, -(2**63))
        self.assertEqual(Foundation.NSUIntegerMax, 2**64 - 1)

        self.assertTrue(objc.YES)
        self.assertFalse(objc.NO)

        self.assertEqual(Foundation.NSOrderedAscending, -1)
        self.assertEqual(Foundation.NSOrderedSame, 0)
        self.assertEqual(Foundation.NSOrderedDescending, 1)

        self.assertEqual(Foundation.NSNotFound, Foundation.NSIntegerMax)

    @min_os_level("10.6")
    def testConstants10_6(self):
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5, 677.00)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_1, 677.10)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_2, 677.15)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_3, 677.19)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_4, 677.19)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_5, 677.21)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_5_6, 677.22)

        self.assertEqual(Foundation.NSEnumerationConcurrent, 1 << 0)
        self.assertEqual(Foundation.NSEnumerationReverse, 1 << 1)
        self.assertEqual(Foundation.NSSortConcurrent, 1 << 0)
        self.assertEqual(Foundation.NSSortStable, 1 << 4)

    @min_os_level("10.7")
    def testConstants10_7(self):
        self.assertEqual(Foundation.NSFoundationVersionNumber10_7, 833.10)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_7_1, 833.10)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_7_2, 833.20)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_7_3, 833.24)
        self.assertEqual(Foundation.NSFoundationVersionNumber10_7_4, 833.25)

    def testSelectorAccess(self):
        v = Foundation.NSStringFromSelector("description")
        self.assertIsInstance(v, str)
        self.assertEqual(v, "description")

        v = Foundation.NSSelectorFromString("description")
        self.assertIsInstance(v, str)
        self.assertEqual(v, "description")

    def testClassAccess(self):
        v = Foundation.NSStringFromClass(Foundation.NSObject)
        self.assertIsInstance(v, str)
        self.assertEqual(v, "NSObject")

        v = Foundation.NSClassFromString("NSDictionary")
        self.assertIsInstance(v, objc.objc_class)
        self.assertEqual(v, Foundation.NSDictionary)

    def testProtocolAccess(self):
        p = Foundation.NSProtocolFromString("NSObject")
        self.assertIsInstance(p, objc.formal_protocol)
        v = Foundation.NSStringFromProtocol(p)
        self.assertIsInstance(v, str)
        self.assertEqual(v, "NSObject")

    def testTypeInfo(self):
        rest, size, align = Foundation.NSGetSizeAndAlignment(b"ii", None, None)
        self.assertEqual(rest, b"i")
        self.assertIsInstance(size, int)
        self.assertIsInstance(align, int)

    def testMinMax(self):
        self.assertEqual(Foundation.MAX(1, 2), 2)
        self.assertEqual(Foundation.MAX(2, 1), 2)
        self.assertEqual(Foundation.MAX("a", "b"), "b")
        self.assertEqual(Foundation.MIN(1, 2), 1)
        self.assertEqual(Foundation.MIN(2, 1), 1)
        self.assertEqual(Foundation.MIN("a", "b"), "a")
        self.assertEqual(Foundation.ABS(1), 1)
        self.assertEqual(Foundation.ABS(-1), 1)
        self.assertEqual(Foundation.ABS(-1.0), 1.0)

    def testFunctions(self):
        self.assertArgIsPrintf(Foundation.NSLog, 0)
