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

// RUN: %empty-directory(%t)
//
// RUN: %gyb %s -o %t/ArrayBridge.swift
// RUN: %target-clang %S/Inputs/ArrayBridge/ArrayBridge.m -c -o %t/ArrayBridgeObjC.o -g
// RUN:  %line-directive %t/ArrayBridge.swift -- %target-build-swift %t/ArrayBridge.swift -I %S/Inputs/ArrayBridge/ -Xlinker %t/ArrayBridgeObjC.o -o %t/ArrayBridge -swift-version 4.2 --

// RUN: %target-codesign %t/ArrayBridge
// RUN: %target-run %t/ArrayBridge
// REQUIRES: executable_test
// REQUIRES: objc_interop

// Requires swift-version 4
// UNSUPPORTED: swift_test_mode_optimize_none_with_implicit_dynamic

import Foundation
import ArrayBridgeObjC
import StdlibUnittest
let tests = TestSuite("ArrayBridge")

var trackedCount = 0
var nextBaseSerialNumber = 0

@objc protocol Fooable {
  func foo()
}

@objc protocol Barable {
  func bar()
}

@objc protocol Bazable {
  func baz()
}

/// A type that will be bridged verbatim to Objective-C
class Base : NSObject, Fooable {
  func foo() { }

  required init(_ value: Int) {
    trackedCount += 1
    nextBaseSerialNumber += 1
    serialNumber = nextBaseSerialNumber
    self.value = value
  }

  deinit {
    assert(serialNumber > 0, "double destruction!")
    trackedCount -= 1
    serialNumber = -serialNumber
  }

  override func isEqual(_ other: Any?) -> Bool {
    return (other as? Base)?.value == self.value
  }

  var value: Int
  var serialNumber: Int
}

class Subclass : Base, Barable {
  func bar() { }
}

var bridgeFromOperationCount = 0
var bridgeToOperationCount = 0

/// A value type that's bridged using _ObjectiveCBridgeable
struct BridgeableValue : _ObjectiveCBridgeable, Equatable {
  func _bridgeToObjectiveC() -> Subclass {
    bridgeToOperationCount += 1
    return Subclass(trak.value)
  }

  static func _forceBridgeFromObjectiveC(
    _ x: Subclass,
    result: inout BridgeableValue?
  ) {
    assert(x.value >= 0, "not bridged")
    bridgeFromOperationCount += 1
    result = BridgeableValue(x.value)
  }

  static func _conditionallyBridgeFromObjectiveC(
    _ x: Subclass,
    result: inout BridgeableValue?
  ) -> Bool {
    if x.value >= 0 {
      result = BridgeableValue(x.value)
      return true
    }

    result = nil
    return false
  }

  static func _unconditionallyBridgeFromObjectiveC(_ source: Subclass?)
      -> BridgeableValue {
    var result: BridgeableValue?
    _forceBridgeFromObjectiveC(source!, result: &result)
    return result!
  }

  init(_ value: Int) {
    self.trak = Base(value)
  }

  static func resetStats() {
    bridgeFromOperationCount = 0
    bridgeToOperationCount = 0
  }

  var trak: Base
}

func == (lhs: BridgeableValue, rhs: BridgeableValue) -> Bool {
  return lhs.trak.value == rhs.trak.value
}

// A class used to test various Objective-C thunks.
class Thunks : NSObject {
  @objc func createSubclass(_ value: Int) -> AnyObject {
    return Subclass(value)
  }

  @objc func acceptSubclassArray(
    _ x: [Subclass],
    expecting expected: NSArray
  ) {
    expectEqualSequence(
      expected.lazy.map { ObjectIdentifier($0 as AnyObject) },
      x.lazy.map { ObjectIdentifier($0 as AnyObject) }
    )
  }

  @objc func produceSubclassArray(
    _ expectations: NSMutableArray
  ) -> [Subclass] {
    var array: [Subclass] = []
    for i in 0..<5 {
      array.append(Subclass(i))
      expectations.add(array[i])
    }
    return array
  }

  @objc func checkProducedSubclassArray(
    _ produced: NSArray, expecting expected: NSArray
  ) {
    expectEqualSequence(
      expected.lazy.map { ObjectIdentifier($0 as AnyObject) },
      produced.lazy.map { ObjectIdentifier($0 as AnyObject) }
    )
  }

  @objc func acceptBridgeableValueArray(_ raw: NSArray) {
    let x = raw as! [BridgeableValue]
    expectEqualSequence(
      raw.lazy.map { $0 as! BridgeableValue },
      x
    )
  }

  @objc func produceBridgeableValueArray() -> NSArray {
    var array: [BridgeableValue] = []
    for i in 0..<5 {
      array.append(BridgeableValue(i))
    }
    return array as NSArray
  }

  @objc func checkProducedBridgeableValueArray(_ produced: NSArray) {
    expectEqualSequence(
      0..<5,
      produced.lazy.map { ($0 as! Subclass).value })
  }
}


//===--- Bridged Verbatim -------------------------------------------------===//
// Base is "bridged verbatim"
//===----------------------------------------------------------------------===//

tests.test("testBridgedVerbatim") {
  nextBaseSerialNumber = 0
  let bases: [Base] = [Base(100), Base(200), Base(300)]

  //===--- Implicit conversion to/from NSArray ------------------------------===//

  let basesConvertedToNSArray = bases as NSArray
  let firstBase = basesConvertedToNSArray.object(at: 0) as! Base
  expectEqual(100, firstBase.value)
  expectEqual(1, firstBase.serialNumber)

  // Verify that NSArray class methods are inherited by a Swift bridging class.
  let className = String(reflecting: type(of: basesConvertedToNSArray))
  expectTrue(className.hasPrefix("Swift._ContiguousArrayStorage"))
  expectTrue(type(of: basesConvertedToNSArray).supportsSecureCoding)

  //===--- Up- and Down-casts -----------------------------------------------===//
  var subclass: [Subclass] = [Subclass(11), Subclass(22)]
  let subclass0 = subclass

  // upcast is implicit
  let subclassAsBases: [Base] = subclass
  expectEqual(subclass.count, subclassAsBases.count)
  for (x, y) in zip(subclass, subclassAsBases) {
    expectTrue(x === y)
  }

  // Arrays are logically distinct after upcast
  subclass[0] = Subclass(33)

  expectEqual([Subclass(33), Subclass(22)], subclass)
  expectEqual([Subclass(11), Subclass(22)], subclassAsBases)

  expectEqual(subclass0, subclassAsBases as! [Subclass])

}

% for Any in 'Any', 'AnyObject':

tests.test("Another/${Any}") {
  // Create an ordinary NSArray, not a native one
  let nsArrayOfBase: NSArray = NSArray(object: Base(42))

  // NSArray can be unconditionally cast to [${Any}]...

  let nsArrayOfBaseConvertedToAnyArray = nsArrayOfBase
  % if Any == 'Any':
  // FIXME: nsArrayOfBase as [Any] doesn't
  // typecheck.
  as [AnyObject]
  % end
  as [${Any}]

  // Capture the representation of the first element
  let base42: ObjectIdentifier
  do {
    let b = nsArrayOfBase.object(at: 0) as! Base
    expectEqual(42, b.value)
    base42 = ObjectIdentifier(b)
  }

  // ...with the same elements
  expectEqual(
    base42,
    ObjectIdentifier(nsArrayOfBaseConvertedToAnyArray[0] as! Base))

  let subclassInBaseBuffer: [Base] = [Subclass(44), Subclass(55)]
  let subclass2 = subclassInBaseBuffer

  // Explicit downcast-ability is based on element type, not buffer type
  expectNotNil(subclassInBaseBuffer as? [Subclass])

  // We can up-cast to array of Any
  let subclassAsAnyArray: [${Any}] = subclassInBaseBuffer
  expectEqual(subclass2, subclassAsAnyArray.map { $0 as! Base })

  let downcastBackToBase = subclassAsAnyArray as? [Base]
  expectNotNil(downcastBackToBase)

  if let downcastBackToSubclass = expectNotNil(subclassAsAnyArray as? [Subclass]) {
    expectEqual(subclass2, downcastBackToSubclass)
  }

  if let downcastToProtocols = expectNotNil(subclassAsAnyArray as? [Fooable]) {
    expectEqual(subclass2, downcastToProtocols.map { $0 as! Subclass })
  }

  if let downcastToProtocols = expectNotNil(subclassAsAnyArray as? [Barable]) {
    expectEqual(subclass2, downcastToProtocols.map { $0 as! Subclass })
  }

  if let downcastToProtocols = expectNotNil(subclassAsAnyArray as? [Barable & Fooable]) {
    expectEqual(subclass2, downcastToProtocols.map { $0 as! Subclass })
  }

  expectNil(subclassAsAnyArray as? [Barable & Bazable])
}

//===--- Explicitly Bridged -----------------------------------------------===//
// BridgeableValue conforms to _ObjectiveCBridgeable
//===----------------------------------------------------------------------===//
tests.test("testExplicitlyBridged/${Any}") {

  let bridgeableValues = [BridgeableValue(42), BridgeableValue(17)]

  let bridgeableValuesAsNSArray = bridgeableValues as NSArray
  expectEqual(2, bridgeableValuesAsNSArray.count)
  expectEqual(42, (bridgeableValuesAsNSArray[0] as! Subclass).value)
  expectEqual(17, (bridgeableValuesAsNSArray[1] as! Subclass).value)

  // Make sure we can bridge back.
  let roundTrippedValues = Swift._forceBridgeFromObjectiveC(
    bridgeableValuesAsNSArray, [BridgeableValue].self)

  // Expect equal values...
  expectEqualSequence(bridgeableValues, roundTrippedValues)
  // ...with the same identity for some reason? FIXME: understand why.
  expectFalse(
    zip(bridgeableValues, roundTrippedValues).contains { $0.trak !== $1.trak })

  // Make a real Cocoa NSArray of these...
  let cocoaBridgeableValues = NSArray(
    array: bridgeableValuesAsNSArray
    %if Any == 'Any':
    // FIXME: should just be "as [Any]" but the typechecker doesn't allow it
    // yet.
    as [AnyObject] as [Any] as [AnyObject]
    %else:
    as [${Any}]
    %end
  )

  // ...and bridge *that* back
  let bridgedBackSwifts = Swift._forceBridgeFromObjectiveC(
    cocoaBridgeableValues, [BridgeableValue].self)

  // Expect equal, but distinctly created instances
  expectEqualSequence(bridgeableValues, bridgedBackSwifts)
  expectFalse(
    zip(bridgedBackSwifts, roundTrippedValues).contains { $0.trak === $1.trak })
  expectFalse(
    zip(bridgedBackSwifts, bridgeableValues).contains { $0.trak === $1.trak })

  let expectedSubclasses = [Subclass(42), Subclass(17)]
  let expectedBases = expectedSubclasses.lazy.map { $0 as Base }

  // Up-casts.
  let bridgeableValuesAsSubclasses = bridgeableValues as [Subclass]
  expectEqualSequence(expectedSubclasses, bridgeableValuesAsSubclasses)

  let bridgeableValuesAsBases = bridgeableValues as [Base]
  expectEqualSequence(expectedBases, bridgeableValuesAsBases)

  let bridgeableValuesAsAnys = bridgeableValues as [Any]
  expectEqualSequence(
    expectedBases,
    bridgeableValuesAsAnys.lazy.map { $0 as! Base })

  // Downcasts of non-verbatim bridged value types to objects.
  do {
    let downcasted = bridgeableValues as [Subclass]
    expectEqualSequence(expectedSubclasses, downcasted)
  }

  do {
    let downcasted = bridgeableValues as [Base]
    expectEqualSequence(expectedBases, downcasted)
  }

  do {
    let downcasted = bridgeableValues as [${Any}]
    expectEqualSequence(expectedBases, downcasted.map { $0 as! Base })
  }

  // Downcasts of up-casted arrays.
  if let downcasted = expectNotNil(
    bridgeableValuesAsAnys as? [Subclass]
  ) {
    expectEqualSequence(expectedSubclasses, downcasted)
  }

  if let downcasted = bridgeableValuesAsAnys as? [Base] {
    expectEqualSequence(expectedBases, downcasted)
  }

  // Downcast of Cocoa array to an array of classes.
  let wrappedCocoaBridgeableValues = cocoaBridgeableValues
  %if Any == 'Any':
  // FIXME: should just be "as [Any]" but typechecker doesn't allow it
  // yet.
  as [AnyObject]
  %end
  as [${Any}]

  if let downcasted = wrappedCocoaBridgeableValues as? [Subclass] {
    expectEqualSequence(expectedSubclasses, downcasted)
  }

  // Downcast of Cocoa array to an array of values.
  if let downcasted = wrappedCocoaBridgeableValues as? [BridgeableValue] {
    expectEqualSequence(bridgeableValues, downcasted)
  }

  // Downcast of Cocoa array to an array of strings (which should fail)
  expectNil(wrappedCocoaBridgeableValues as? [String])

  // Downcast from an implicitly unwrapped optional array of Anys.
  var wrappedCocoaBridgeableValuesIUO: [${Any}]! = wrappedCocoaBridgeableValues
  if let downcasted = wrappedCocoaBridgeableValuesIUO as? [BridgeableValue] {
    expectEqualSequence(bridgeableValues, downcasted)
  }

  // Downcast from a nil implicitly unwrapped optional array of Anys.
  wrappedCocoaBridgeableValuesIUO = nil
  expectNil(wrappedCocoaBridgeableValuesIUO as? [BridgeableValue])

  // Downcast from an optional array of Anys.
  var wrappedCocoaBridgeableValuesOpt: [${Any}]? = wrappedCocoaBridgeableValues
  if let downcasted = wrappedCocoaBridgeableValuesOpt as? [BridgeableValue] {
    expectEqualSequence(bridgeableValues, downcasted)
  }

  // Downcast from a nil optional array of Anys.
  wrappedCocoaBridgeableValuesOpt = nil
  expectNil(wrappedCocoaBridgeableValuesOpt as? [BridgeableValue])
}
% end

tests.test("testThunks") {
  testSubclass(Thunks())
  testBridgeableValue(Thunks())
}


tests.test("testRoundTrip") {
  class Test : NSObject {
    @objc dynamic func call(_ array: NSArray) -> NSArray {

      let result = array as! [BridgeableValue]
      expectEqual(0, bridgeFromOperationCount)
      expectEqual(0, bridgeToOperationCount)

      // Clear out the stats before returning array
      BridgeableValue.resetStats()
      return result as NSArray
    }
  }

  let test = Test()

  let array = [
    BridgeableValue(10), BridgeableValue(20), BridgeableValue(30),
    BridgeableValue(40), BridgeableValue(50) ]

  BridgeableValue.resetStats()
  _ = test.call(array as NSArray)

  expectEqual(0, bridgeFromOperationCount)
  expectEqual(0, bridgeToOperationCount)
}

//===--- Non-bridging -----------------------------------------------------===//
// X is not bridged to Objective-C
//===----------------------------------------------------------------------===//

struct X {}

tests.test("testMutableArray") {
  let m = NSMutableArray(array: ["fu", "bar", "buzz"])
  let a = m as NSArray as! [NSString]

  // Create distinct array storage with a copy of the elements in a
  let aCopy = Array(a)

  // Modify the original mutable array
  m.add("goop")

  // Check that our [NSString] is unaffected
  expectEqualSequence(aCopy, a)
}

tests.test("rdar://problem/27905230") {
  let dict = RDar27905230.mutableDictionaryOfMutableLists()!
  let arr = dict["list"]!
  expectEqual(arr[0] as! NSNull, NSNull())
  expectEqual(arr[1] as! String, "")
  expectEqual(arr[2] as! Int, 1)
  expectEqual(arr[3] as! Bool, true)
  expectEqual((arr[4] as! NSValue).rangeValue.location, 0)
  expectEqual((arr[4] as! NSValue).rangeValue.length, 1)
  expectEqual(arr[5] as! Date, Date(timeIntervalSince1970: 0))
}

runAllTests()
