// RUN: %target-run-simple-swift
// REQUIRES: executable_test

// REQUIRES: objc_interop

import Foundation
import StdlibUnittest


// rdar://problem/18884272
// Make sure that NSObject conforms to NSObjectProtocol. This
// particular bug is ridiculously hard to trigger without a complete
// SDK, so it sits here.
let objcProtocol: NSObjectProtocol = NSObject()

var FoundationTestSuite = TestSuite("Foundation")

func asNSString(_ s: String) -> NSString { return s as NSString }
func asString(_ ns: NSString) -> String { return ns as String }

//===----------------------------------------------------------------------===//
// Strings
//===----------------------------------------------------------------------===//

FoundationTestSuite.test("NSString") {
  var str = "Hello"
  var nsStr = str as NSString
  assert(nsStr.compare(str).rawValue == ComparisonResult.orderedSame.rawValue)
  assert(nsStr.compare(str) == ComparisonResult.orderedSame)
  nsStr = "World"
  str = nsStr as String
  // FIXME: Shouldn't need coercion here to resolve ambiguity. <rdar://problem/14637688>
  assert(str == asString(nsStr))
}

//===----------------------------------------------------------------------===//
// Numbers
//===----------------------------------------------------------------------===//

FoundationTestSuite.test("NSNumber") {
  var i = 17
  var d = 3.14159
  var b = true

  // Implicit boxing/explicit unboxing
  var nsNum: NSNumber = i as NSNumber
  expectEqual(i, Int(nsNum))

  nsNum = d as NSNumber
  expectEqual(d, Double(nsNum))

  nsNum = b as NSNumber
  expectEqual(b, Bool(nsNum))

  // Literals
  nsNum = 42
  expectEqual(42, Int(nsNum))

  nsNum = 3.14159
  expectEqual(3.14159, Double(nsNum))

  nsNum = false
  expectEqual(false, Bool(nsNum))
}

//===----------------------------------------------------------------------===//
// Arrays
//===----------------------------------------------------------------------===//

FoundationTestSuite.test("NSArray") {
  // Literals
  var nsArr: NSArray = [1, 2.5, "Hello"]
  assert(nsArr.count == 3)

  // Subscripting
  expectEqual(1, Int(nsArr[0] as! NSNumber))
  expectEqual(2.5, Double(nsArr[1] as! NSNumber))
  expectTrue((nsArr[2] as! NSString).isEqual("Hello"))

  // Iteration
  var result = [String]()
  for x: Any in nsArr {
    result.append((x as! NSObject).description)
  }
  expectEqualSequence(["1", "2.5", "Hello"], result)
}

FoundationTestSuite.test("NSMutableArray") {
  let nsMutableArr: NSMutableArray = ["Constant", "Moon"]
  nsMutableArr[0] = "Inconstant"

  expectEqual(2, nsMutableArr.count)
  expectEqual("Inconstant", nsMutableArr[0] as! NSString)
  expectEqual("Moon", nsMutableArr[1] as! NSString)
}

FoundationTestSuite.test("NSArrayVariadicInit") {
  let variadicArray = NSArray(objects: "A", "B", "C")
  expectEqual(3, variadicArray.count)
}

FoundationTestSuite.test("arrayConversions") {
  var nsa = NSArray()
  var aoa: Array<AnyObject> = []

  nsa as Array<AnyObject>
  var nsa2 = NSArray()
  var aoa2 = nsa2 as Array<AnyObject>

  var nsaoa = aoa as NSArray

  func nsArrayToAnyObjectArray(_ nsa: NSArray) -> [AnyObject] {
    return nsa as [AnyObject]
  }

  nsArrayToAnyObjectArray(nsa)
  nsArrayToAnyObjectArray(aoa as NSArray)
}

//===----------------------------------------------------------------------===//
// Dictionaries
//===----------------------------------------------------------------------===//

FoundationTestSuite.test("NSDictionary") {
  var nsDict : NSDictionary = [1 : "Hello", 2 : "World"]
  assert((nsDict[1]! as! NSString).isEqual("Hello"))
  assert((nsDict[2]! as! NSString).isEqual("World"))

  let nsMutableDict: NSMutableDictionary = ["Hello" : 1, "World" : 2 as NSNumber]
  assert((nsMutableDict["Hello"]! as AnyObject).isEqual(1))
  assert((nsMutableDict["World"]! as AnyObject).isEqual(2))
}

//===----------------------------------------------------------------------===//
// Ranges
//===----------------------------------------------------------------------===//

FoundationTestSuite.test("NSRange") {
  let nsRange = NSRange(1..<5)
  expectEqual("{1, 4}", String(NSStringFromRange(nsRange)))
}

FoundationTestSuite.test("RangeConversion") {
  let i: Int8 = 10
  let j: Int8 = 20

  let nsrFromInt8 = NSRange(i..<j)
  expectEqual(nsrFromInt8, NSRange(location: 10, length: 10))

  var r = Range(nsrFromInt8)
  expectNotNil(r)
  expectEqual(r!.lowerBound, 10)
  expectEqual(r!.upperBound, 20)
  expectType(Optional<Range<Int>>.self, &r)

  var r8 = Range<Int8>(nsrFromInt8)
  expectNotNil(r8 != nil)
  expectEqual(r8?.lowerBound, 10)
  expectEqual(r8?.upperBound, 20)
  expectType(Optional<Range<Int8>>.self, &r8)
  
  var nsrFromPartial = NSRange(..<5)
  expectEqual("{0, 5}", NSStringFromRange(nsrFromPartial))

  let s = "Hello, 🌎!"
  let b = s.index(of: ",")!
  let e = s.index(of: "!")!
  let nsr = NSRange(b..<e, in: s)
  expectEqual(nsr.location, 5)
  expectEqual(nsr.length, 4)
  let rs = Range(nsr, in: s)!
  expectEqual(s[rs], ", 🌎")

  let nsrTo = NSRange(..<b, in: s)
  expectEqual(nsrTo.location, 0)
  expectEqual(nsrTo.length, 5)
  let nsrFrom = NSRange(b..., in: s)
  expectEqual(nsrFrom.location,5)
  expectEqual(nsrFrom.length, 5)
  
  expectNil(Range(NSRange(location: 100, length: 0), in: s))
  expectNil(Range(NSRange(location: 0, length: 100), in: s))
  
  let empty = ""
  expectNil(Range(NSRange(location: 1, length: 0), in: empty))  
  expectNil(Range(NSRange(location: 0, length: 1), in: empty))
  expectNotNil(Range(NSRange(location: 0, length: 0), in: empty))

  // FIXME: enable once indices conform to RangeExpression
  // let nsrFull = NSRange(s.indices, in: s)
  // expectEqual(nsrFull.location, 0)
  // expectEqual(nsrFull.length, 10)
}

//===----------------------------------------------------------------------===//
// URLs
//===----------------------------------------------------------------------===//

FoundationTestSuite.test("NSURL") {
  let nsURL = NSURL(string: "http://llvm.org")!
  expectEqual("http://llvm.org", nsURL.description)
}

//===----------------------------------------------------------------------===//
// Pattern-matching
//===----------------------------------------------------------------------===//

func matchesEither(_ input: NSNumber, _ a: NSNumber, _ b: NSNumber) -> Bool {
  switch input {
  case a, b:
    return true
  default:
    return false
  }
}

FoundationTestSuite.test("patternMatching") {
  var one, two, three, oneAgain : NSNumber
  one = NSNumber(value: 1)
  two = NSNumber(value: 2)
  three = NSNumber(value: 3)
  oneAgain = NSNumber(value: 1)
  expectFalse(matchesEither(one, two, three))
  expectTrue(matchesEither(one, oneAgain, three))
  expectTrue(matchesEither(one, two, oneAgain))
}

//===----------------------------------------------------------------------===//
// Miscellaneous
//===----------------------------------------------------------------------===//

// <rdar://problem/14474701>
// Type checker used to crash on this.
class ClassWithDtor : NSObject {
  deinit {
    let noteCenter = NotificationCenter.default
    noteCenter.removeObserver(self, name: Notification.Name(rawValue: "ReceivedContentNotification"), object: nil)
  }
}

FoundationTestSuite.test("rdar://17584531") {
  // <rdar://problem/17584531>
  // Type checker used to be confused by this.
  var dict: NSDictionary = ["status": 200, "people": [["id": 255, "name": ["first": "John", "last": "Appleseed"] as NSDictionary] as NSDictionary] as NSArray]
  var dict2 = dict["people"].flatMap { $0 as? NSArray }?[0] as! NSDictionary
  expectEqual("Optional(255)", String(describing: dict2["id" as NSString]))
}

FoundationTestSuite.test("DarwinBoolean smoke test") {
  expectFalse(CFEqual("abc" as NSString as CFString, "def" as NSString as CFString))

  let _: CFArrayEqualCallBack = { DarwinBoolean($0 == $1) }
}

#if os(macOS)
FoundationTestSuite.test("NSRectEdge/constants") {
  // Check that the following constants have the correct type and value.
  //
  // It is valid to hardcode the value in the test.  The way they are currently
  // defined in the SDK makes them ABI for Objective-C code.
  expectEqual(0, CGRectEdge(rectEdge: NSRectEdge.minX).rawValue)
  expectEqual(0, NSRectEdge(rectEdge: CGRectEdge.minXEdge).rawValue)

  expectEqual(1, CGRectEdge(rectEdge: NSRectEdge.minY).rawValue)
  expectEqual(1, NSRectEdge(rectEdge: CGRectEdge.minYEdge).rawValue)

  expectEqual(2, CGRectEdge(rectEdge: NSRectEdge.maxX).rawValue)
  expectEqual(2, NSRectEdge(rectEdge: CGRectEdge.maxXEdge).rawValue)

  expectEqual(3, CGRectEdge(rectEdge: NSRectEdge.maxY).rawValue)
  expectEqual(3, NSRectEdge(rectEdge: CGRectEdge.maxYEdge).rawValue)
}
#endif


if #available(OSX 10.11, iOS 9.0, *) {
  FoundationTestSuite.test("UndoManager/ObjCClass") {
    let UM = UndoManager()

    // Confirm with an ObjC class.
    class ObjCClass : NSObject {
      var someProperty: String = ""
    }
    let f = ObjCClass()
    UM.registerUndo(withTarget: f) { target in
      target.someProperty = "expected"
    }
    UM.undo()
    expectEqual(f.someProperty, "expected")
  }

  FoundationTestSuite.test("UndoManager/SwiftClass") {
    let UM = UndoManager()

    // Confirm with a Swift class.
    class SwiftClass {
      var someOtherProperty: String = ""
    }
    var b = SwiftClass()
    UM.registerUndo(withTarget:b) { target in
      target.someOtherProperty = "expected"
    }
    UM.undo()
    expectEqual(b.someOtherProperty, "expected")
  }
}

private let KEY = "some-key"
private func createTestArchive() -> NSData {
  let mutableData = NSMutableData()
  let KA = NSKeyedArchiver(forWritingWith: mutableData)

  // Set up some fake data.
  let obj =  NSPredicate(value: true)
  KA.encode(obj, forKey: KEY)
  KA.encode(obj, forKey: NSKeyedArchiveRootObjectKey)
  KA.finishEncoding()

  return mutableData
}

FoundationTestSuite.test("NSKeyedUnarchiver/decodeObjectOfClass(_:forKey:)") {
  let obj = NSPredicate(value: true)
  let data = createTestArchive()

  var KU = NSKeyedUnarchiver(forReadingWith: data as Data)

  var missing = KU.decodeObject(of: NSPredicate.self, forKey: "Not there")
  expectNil(missing)
  expectType((NSPredicate?).self, &missing)

  var decoded = KU.decodeObject(of: NSPredicate.self, forKey: KEY)
  expectNotNil(decoded)
  expectType((NSPredicate?).self, &decoded)

  var wrongType = KU.decodeObject(of: DateFormatter.self, forKey: KEY)
  expectNil(missing)

  KU.finishDecoding()
}

if #available(OSX 10.11, iOS 9.0, *) {
  FoundationTestSuite.test("NSKeyedUnarchiver/decodeTopLevel*") {
    let obj = NSPredicate(value: true)
    let data = createTestArchive()

    // first confirm .decodeObjectWithClasses overlay requires an array of classes
    var KU = NSKeyedUnarchiver(forReadingWith: data as Data)
    var nonTopLevelResult = KU.decodeObject(of: [NSPredicate.self], forKey: KEY)
    expectTrue(nonTopLevelResult != nil)
    KU.finishDecoding()

    KU = NSKeyedUnarchiver(forReadingWith: data as Data)
    do {
      // decodeObjectForKey(_:) throws
      let decoded1 = try KU.decodeTopLevelObject(forKey: KEY) as? NSPredicate
      let missing1 = try KU.decodeTopLevelObject(forKey:"Not there")
      expectTrue(decoded1 != nil)
      expectEqual(obj, decoded1)
      expectTrue(missing1 == nil)
      KU.finishDecoding()

      // recreate so we can do the rest securely
      KU = NSKeyedUnarchiver(forReadingWith: data as Data)
      KU.requiresSecureCoding = true

      // decodeObjectOfClass(_:,forKey:) throws
      let decoded2 = try KU.decodeTopLevelObject(of: NSPredicate.self, forKey: KEY)
      let missing2 = try KU.decodeTopLevelObject(of: NSPredicate.self, forKey: "Not there")
      expectTrue(decoded2 != nil)
      expectEqual(obj, decoded2)
      expectTrue(missing2 == nil)

      let classes: [AnyClass] = [NSPredicate.self]
      let decoded3 = try KU.decodeTopLevelObject(of: classes, forKey: KEY) as? NSPredicate
      let missing3 = try KU.decodeTopLevelObject(of: classes, forKey: "Not there")
      expectTrue(decoded3 != nil)
      expectEqual(obj, decoded3)
      expectTrue(missing3 == nil)
    }
    catch {
      expectTrue(false) // should have no errors
    }
    KU.finishDecoding()

    KU = NSKeyedUnarchiver(forReadingWith: data as Data)
    KU.requiresSecureCoding = true
    do {
      // recreate so we avoid caches from above
      let wrong = try KU.decodeTopLevelObject(of: DateFormatter.self, forKey: KEY)
      expectUnreachable() // should have error
    }
    catch {
      // expected
    }
    KU.finishDecoding()
    KU = NSKeyedUnarchiver(forReadingWith: data as Data)
    KU.requiresSecureCoding = true
    do {
      let wrongClasses: [AnyClass] = [DateFormatter.self]
      let wrong = try KU.decodeTopLevelObject(of: wrongClasses, forKey: KEY)
      expectUnreachable() // should have error
    }
    catch {
      // expected
    }
    KU.finishDecoding()

    // confirm the that class function works
    do {
      let decoded = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? NSPredicate
      expectEqual(obj, decoded)
    }
    catch {
      expectUnreachableCatch(error)
    }
  }

  FoundationTestSuite.test("NSKeyedUnarchiver/decodeTopLevelObjectOfClass(_:forKey:)/trap") {
    let obj = NSPredicate(value: true)
    let data = createTestArchive()

    var KU = NSKeyedUnarchiver(forReadingWith: data as Data)

    // Even though we're doing non-secure coding, this should still be checked
    // in Swift.
    do {
      var wrongType = try KU.decodeTopLevelObject(of: DateFormatter.self, forKey: KEY)
      expectType((DateFormatter?).self, &wrongType)
    } catch {
      expectUnreachableCatch(error)
    }

    KU.finishDecoding()
  }
}

FoundationTestSuite.test("NotificationCenter/addObserver(_:selector:name:object:)") {
  let obj: AnyObject = "Hello" as NSString
  NotificationCenter.default.addObserver(obj, selector: Selector("blah:"),
                                         name: nil, object: nil)
  let name = "hello"
  NotificationCenter.default.addObserver(obj, selector: Selector("blarg:"),
                                         name: Notification.Name(name),
                                         object: nil)
}

runAllTests()

