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

import StdlibUnittest


import Foundation
import CoreLocation
import Darwin

var ErrorBridgingTests = TestSuite("ErrorBridging")

var NoisyErrorLifeCount = 0
var NoisyErrorDeathCount = 0
var CanaryHandle = 0

protocol OtherProtocol {
  var otherProperty: String { get }
}

protocol OtherClassProtocol : class {
  var otherClassProperty: String { get }
}

class NoisyError : Error, OtherProtocol, OtherClassProtocol {
  init() { NoisyErrorLifeCount += 1 }
  deinit { NoisyErrorDeathCount += 1 }

  let _domain = "NoisyError"
  let _code = 123

  let otherProperty = "otherProperty"
  let otherClassProperty = "otherClassProperty"
}

@objc enum EnumError : Int, Error {
  case BadError = 9000
  case ReallyBadError = 9001
}

ErrorBridgingTests.test("NSError") {
  NoisyErrorLifeCount = 0
  NoisyErrorDeathCount = 0
  autoreleasepool {
    let ns = NSError(domain: "SomeDomain", code: 321, userInfo: nil)

    objc_setAssociatedObject(ns, &CanaryHandle, NoisyError(),
                             .OBJC_ASSOCIATION_RETAIN_NONATOMIC)

    let e: Error = ns
    expectEqual(e._domain, "SomeDomain")
    expectEqual(e._code, 321)

    let ns2 = e as NSError
    expectTrue(ns === ns2)
    expectEqual(ns2._domain, "SomeDomain")
    expectEqual(ns2._code, 321)
  }
  expectEqual(NoisyErrorDeathCount, NoisyErrorLifeCount)
}

ErrorBridgingTests.test("NSCopying") {
  autoreleasepool {
    let orig = EnumError.ReallyBadError as NSError
    let copy = orig.copy() as! NSError
    expectEqual(orig, copy)
  }
}

func archiveAndUnarchiveObject<T: NSCoding where T: NSObject>(
  _ object: T
) -> T? {
  let unarchiver = NSKeyedUnarchiver(forReadingWith:
    NSKeyedArchiver.archivedData(withRootObject: object)
  )
  unarchiver.requiresSecureCoding = true
  return unarchiver.decodeObject(of: T.self, forKey: "root")
}
ErrorBridgingTests.test("NSCoding") {
  autoreleasepool {
    let orig = EnumError.ReallyBadError as NSError
    let unarchived = archiveAndUnarchiveObject(orig)!
    expectEqual(orig, unarchived)
    expectTrue(type(of: unarchived) == NSError.self)
  }
}

ErrorBridgingTests.test("NSError-to-enum bridging") {
  NoisyErrorLifeCount = 0
  NoisyErrorDeathCount = 0
  let testURL = URL(string: "http://swift.org")!

  autoreleasepool {
    let underlyingError = CocoaError(.fileLockingError)
      as Error as NSError
    let ns = NSError(domain: NSCocoaErrorDomain,
                     code: NSFileNoSuchFileError,
                     userInfo: [
                       AnyHashable(NSFilePathErrorKey): "/dev/null",
                       AnyHashable(NSStringEncodingErrorKey): /*ASCII=*/1,
                       AnyHashable(NSUnderlyingErrorKey): underlyingError,
                       AnyHashable(NSURLErrorKey): testURL
                     ])

    objc_setAssociatedObject(ns, &CanaryHandle, NoisyError(),
                             .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
  
    let e: Error = ns

    let cocoaCode: Int?
    switch e {
    case let x as CocoaError:
      cocoaCode = x._code
      expectTrue(x.isFileError)
      expectEqual(x.code, CocoaError.fileNoSuchFileError)
    default:
      cocoaCode = nil
    }

    expectEqual(NSFileNoSuchFileError, cocoaCode)

    let cocoaCode2: Int? = (ns as? CocoaError)?._code
    expectEqual(NSFileNoSuchFileError, cocoaCode2)

    let isNoSuchFileError: Bool
    switch e {
    case CocoaError.fileNoSuchFileError:
      isNoSuchFileError = true
    default:
      isNoSuchFileError = false
    }

    expectTrue(isNoSuchFileError)

    // Check the contents of the error.
    let cocoaError = e as! CocoaError
    expectOptionalEqual("/dev/null", cocoaError.filePath)
    expectOptionalEqual(String.Encoding.ascii, cocoaError.stringEncoding)
    expectOptionalEqual(underlyingError, cocoaError.underlying.map { $0 as NSError })
    expectOptionalEqual(testURL, cocoaError.url)

    // URLError domain
    let nsURL = NSError(domain: NSURLErrorDomain,
                        code: NSURLErrorBadURL,
                        userInfo: [AnyHashable(NSURLErrorFailingURLErrorKey): testURL])
    let eURL: Error = nsURL
    let isBadURLError: Bool
    switch eURL {
    case URLError.badURL:
      isBadURLError = true
    default:
      isBadURLError = false
    }

    expectTrue(isBadURLError)

    let urlError = eURL as! URLError
    expectOptionalEqual(testURL, urlError.failingURL)
    expectEmpty(urlError.failureURLPeerTrust)

    // CoreLocation error domain
    let nsCL = NSError(domain: kCLErrorDomain,
                       code: CLError.headingFailure.rawValue,
                       userInfo: [AnyHashable(NSURLErrorKey): testURL])
    let eCL: Error = nsCL
    let isHeadingFailure: Bool
    switch eCL {
    case CLError.headingFailure:
      isHeadingFailure = true
    default:
      isHeadingFailure = false
    }

    let isCLError: Bool
    switch eCL {
    case let error as CLError:
      isCLError = true
      expectOptionalEqual(testURL, (error as NSError).userInfo[NSURLErrorKey as NSObject] as? URL)
      expectOptionalEqual(testURL, error.userInfo[NSURLErrorKey] as? URL)
    default:
      isCLError = false
    }

    expectTrue(isCLError)

    // NSPOSIXError domain
    let nsPOSIX = NSError(domain: NSPOSIXErrorDomain,
                          code: Int(EDEADLK),
                          userInfo: [:])
    let ePOSIX: Error = nsPOSIX
    let isDeadlock: Bool
    switch ePOSIX {
    case POSIXError.EDEADLK:
      isDeadlock = true
    default:
      isDeadlock = false
    }

    expectTrue(isDeadlock)

    // NSMachError domain
    let nsMach = NSError(domain: NSMachErrorDomain,
                         code: Int(KERN_MEMORY_FAILURE),
                         userInfo: [:])
    let eMach: Error = nsMach
    let isMemoryFailure: Bool
    switch eMach {
    case MachError.memoryFailure:
      isMemoryFailure = true
    default:
      isMemoryFailure = false
    }

    expectTrue(isMemoryFailure)
  }
  
  expectEqual(NoisyErrorDeathCount, NoisyErrorLifeCount)
}

func opaqueUpcastToAny<T>(_ x: T) -> Any {
  return x
}

struct StructError: Error {
  var _domain: String { return "StructError" }
  var _code: Int { return 4812 }
}

ErrorBridgingTests.test("Error-to-NSError bridging") {
  NoisyErrorLifeCount = 0
  NoisyErrorDeathCount = 0
  autoreleasepool {
    let e: Error = NoisyError()
    let ns = e as NSError
    let ns2 = e as NSError
    expectTrue(ns === ns2)
    expectEqual(ns._domain, "NoisyError")
    expectEqual(ns._code, 123)

    let e3: Error = ns
    expectEqual(e3._domain, "NoisyError")
    expectEqual(e3._code, 123)
    let ns3 = e3 as NSError
    expectTrue(ns === ns3)

    let nativeNS = NSError(domain: NSCocoaErrorDomain,
                           code: NSFileNoSuchFileError,
                           userInfo: nil)

    objc_setAssociatedObject(ns, &CanaryHandle, NoisyError(),
                             .OBJC_ASSOCIATION_RETAIN_NONATOMIC)

    let nativeE: Error = nativeNS
    let nativeNS2 = nativeE as NSError
    expectTrue(nativeNS === nativeNS2)
    expectEqual(nativeNS2._domain, NSCocoaErrorDomain)
    expectEqual(nativeNS2._code, NSFileNoSuchFileError)

    let any: Any = NoisyError()
    let ns4 = any as! NSError
    expectEqual(ns4._domain, "NoisyError")
    expectEqual(ns4._code, 123)

    let ao: AnyObject = NoisyError()
    let ns5 = ao as! NSError
    expectEqual(ns5._domain, "NoisyError")
    expectEqual(ns5._code, 123)

    let any2: Any = StructError()
    let ns6 = any2 as! NSError
    expectEqual(ns6._domain, "StructError")
    expectEqual(ns6._code, 4812)
  }
  expectEqual(NoisyErrorDeathCount, NoisyErrorLifeCount)
}

ErrorBridgingTests.test("enum-to-NSError round trip") {
  autoreleasepool {
    // Emulate throwing an error from Objective-C.
    func throwNSError(_ error: EnumError) throws {
      throw NSError(domain: "main.EnumError", code: error.rawValue,
                    userInfo: [:])
    }

    var caughtError: Bool

    caughtError = false
    do {
      try throwNSError(.BadError)
      expectUnreachable()
    } catch let error as EnumError {
      expectEqual(.BadError, error)
      caughtError = true
    } catch _ {
      expectUnreachable()
    }
    expectTrue(caughtError)

    caughtError = false
    do {
      try throwNSError(.ReallyBadError)
      expectUnreachable()
    } catch EnumError.BadError {
      expectUnreachable()
    } catch EnumError.ReallyBadError {
      caughtError = true
    } catch _ {
      expectUnreachable()
    }
    expectTrue(caughtError)
  }
}

class SomeNSErrorSubclass: NSError {}


ErrorBridgingTests.test("Thrown NSError identity is preserved") {
  do {
    let e = NSError(domain: "ClericalError", code: 219,
                    userInfo: [AnyHashable("yeah"): "yeah"])
    do {
      throw e
    } catch let e2 as NSError {
      expectTrue(e === e2)
      expectTrue(e2.userInfo["yeah"] as? String == "yeah")
    } catch {
      expectUnreachable()
    }
  }

  do {
    let f = SomeNSErrorSubclass(domain: "ClericalError", code: 219,
                                userInfo: [AnyHashable("yeah"): "yeah"])
    do {
      throw f
    } catch let f2 as NSError {
      expectTrue(f === f2)
      expectTrue(f2.userInfo["yeah"] as? String == "yeah")
    } catch {
      expectUnreachable()
    }
  }
}

// Check errors customized via protocol.
struct MyCustomizedError : Error {
  let code: Int
}

extension MyCustomizedError : LocalizedError {
  var errorDescription: String? {
    return NSLocalizedString("something went horribly wrong", comment: "")
  }

  var failureReason: String? {
    return NSLocalizedString("because someone wrote 'throw'", comment: "")
  }

  var recoverySuggestion: String? {
    return NSLocalizedString("delete the 'throw'", comment: "")
  }

  var helpAnchor: String? {
    return NSLocalizedString("there is no help when writing tests", comment: "")
  }
}

extension MyCustomizedError : CustomNSError {
  static var errorDomain: String {
    return "custom"
  }

  /// The error code within the given domain.
  var errorCode: Int {
    return code
  }

  /// The user-info dictionary.
  var errorUserInfo: [String : Any] {
    return [NSURLErrorKey : URL(string: "https://swift.org")!]
  }
}

extension MyCustomizedError : RecoverableError {
  var recoveryOptions: [String] {
    return ["Delete 'throw'", "Disable the test" ]
  }

  func attemptRecovery(optionIndex recoveryOptionIndex: Int) -> Bool {
    return recoveryOptionIndex == 0
  }
}

/// An error type that provides localization and recovery, but doesn't
/// customize NSError directly.
enum MySwiftCustomizedError : Error {
  case failed
  static var errorDescriptionCount = 0
}

extension MySwiftCustomizedError : LocalizedError {
  var errorDescription: String? {
    MySwiftCustomizedError.errorDescriptionCount =
      MySwiftCustomizedError.errorDescriptionCount + 1
    return NSLocalizedString("something went horribly wrong", comment: "")
  }

  var failureReason: String? {
    return NSLocalizedString("because someone wrote 'throw'", comment: "")
  }

  var recoverySuggestion: String? {
    return NSLocalizedString("delete the 'throw'", comment: "")
  }

  var helpAnchor: String? {
    return NSLocalizedString("there is no help when writing tests", comment: "")
  }
}

extension MySwiftCustomizedError : RecoverableError {
  var recoveryOptions: [String] {
    return ["Delete 'throw'", "Disable the test" ]
  }

  func attemptRecovery(optionIndex recoveryOptionIndex: Int) -> Bool {
    return recoveryOptionIndex == 0
  }
}

/// Fake definition of the informal protocol
/// "NSErrorRecoveryAttempting" that we use to poke at the object
/// produced for a RecoverableError.
@objc protocol FakeNSErrorRecoveryAttempting {
  @objc(attemptRecoveryFromError:optionIndex:delegate:didRecoverSelector:contextInfo:)
  func attemptRecovery(fromError nsError: Error,
                       optionIndex recoveryOptionIndex: Int,
                       delegate: AnyObject?,
                       didRecoverSelector: Selector,
                       contextInfo: UnsafeMutableRawPointer?)

  @objc(attemptRecoveryFromError:optionIndex:)
  func attemptRecovery(fromError nsError: Error,
                       optionIndex recoveryOptionIndex: Int) -> Bool
}

class RecoveryDelegate {
  let expectedSuccess: Bool
  let expectedContextInfo: UnsafeMutableRawPointer?
  var called = false

  init(expectedSuccess: Bool,
       expectedContextInfo: UnsafeMutableRawPointer?) {
    self.expectedSuccess = expectedSuccess
    self.expectedContextInfo = expectedContextInfo
  }

  @objc func recover(success: Bool, contextInfo: UnsafeMutableRawPointer?) {
    expectEqual(expectedSuccess, success)
    expectEqual(expectedContextInfo, contextInfo)
    called = true
  }
}

/// Helper for testing a customized error.
func testCustomizedError(error: Error, nsError: NSError) {
  // LocalizedError
  if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
    expectEmpty(nsError.userInfo[NSLocalizedDescriptionKey as NSObject])
    expectEmpty(nsError.userInfo[NSLocalizedFailureReasonErrorKey as NSObject])
    expectEmpty(nsError.userInfo[NSLocalizedRecoverySuggestionErrorKey as NSObject])
    expectEmpty(nsError.userInfo[NSHelpAnchorErrorKey as NSObject])
  } else {
    expectOptionalEqual("something went horribly wrong",
      nsError.userInfo[NSLocalizedDescriptionKey as NSObject] as? String)
    expectOptionalEqual("because someone wrote 'throw'",
      nsError.userInfo[NSLocalizedFailureReasonErrorKey as NSObject] as? String)
    expectOptionalEqual("delete the 'throw'",
      nsError.userInfo[NSLocalizedRecoverySuggestionErrorKey as NSObject] as? String)
    expectOptionalEqual("there is no help when writing tests",
      nsError.userInfo[NSHelpAnchorErrorKey as NSObject] as? String)
  }
  expectEqual("something went horribly wrong", error.localizedDescription)
  expectEqual("something went horribly wrong", nsError.localizedDescription)
  expectEqual("because someone wrote 'throw'", nsError.localizedFailureReason)
  expectEqual("delete the 'throw'", nsError.localizedRecoverySuggestion)
  expectEqual("there is no help when writing tests", nsError.helpAnchor)

  // RecoverableError
  if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
    expectEmpty(nsError.userInfo[NSLocalizedRecoveryOptionsErrorKey as NSObject])
  } else {
    expectOptionalEqual(["Delete 'throw'", "Disable the test" ],
      nsError.userInfo[NSLocalizedRecoveryOptionsErrorKey as NSObject] as? [String])
  }
  expectOptionalEqual(["Delete 'throw'", "Disable the test" ],
    nsError.localizedRecoveryOptions)

  // Directly recover.
  let attempter: AnyObject
  if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
    expectEmpty(nsError.userInfo[NSRecoveryAttempterErrorKey as NSObject])
    attempter = nsError.recoveryAttempter! as AnyObject
  } else {
    attempter = nsError.userInfo[NSRecoveryAttempterErrorKey as NSObject]! as AnyObject
  }
  expectOptionalEqual(attempter.attemptRecovery(fromError: nsError,
                      optionIndex: 0),
    true)
  expectOptionalEqual(attempter.attemptRecovery(fromError: nsError,
                      optionIndex: 1),
    false)

  // Recover through delegate.
  let rd1 = RecoveryDelegate(expectedSuccess: true, expectedContextInfo: nil)
  expectEqual(false, rd1.called)
  attempter.attemptRecovery(
    fromError: nsError,
    optionIndex: 0,
    delegate: rd1,
    didRecoverSelector: #selector(RecoveryDelegate.recover(success:contextInfo:)),
    contextInfo: nil)
  expectEqual(true, rd1.called)

  let rd2 = RecoveryDelegate(expectedSuccess: false, expectedContextInfo: nil)
  expectEqual(false, rd2.called)
  attempter.attemptRecovery(
    fromError: nsError,
    optionIndex: 1,
    delegate: rd2,
    didRecoverSelector: #selector(RecoveryDelegate.recover(success:contextInfo:)),
    contextInfo: nil)
  expectEqual(true, rd2.called)
}

ErrorBridgingTests.test("Customizing NSError via protocols") {
  let error = MyCustomizedError(code: 12345)
  let nsError = error as NSError

  // CustomNSError
  expectEqual("custom", nsError.domain)
  expectEqual(12345, nsError.code)
  expectOptionalEqual(URL(string: "https://swift.org")!,
    nsError.userInfo[NSURLErrorKey as NSObject] as? URL)

  testCustomizedError(error: error, nsError: nsError)
}

ErrorBridgingTests.test("Customizing localization/recovery via protocols") {
  let error = MySwiftCustomizedError.failed
  let nsError = error as NSError
  testCustomizedError(error: error, nsError: nsError)
}

ErrorBridgingTests.test("Customizing localization/recovery laziness") {
  let countBefore = MySwiftCustomizedError.errorDescriptionCount
  let error = MySwiftCustomizedError.failed
  let nsError = error as NSError

  // RecoverableError
  if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
    expectEmpty(nsError.userInfo[NSLocalizedRecoveryOptionsErrorKey as NSObject])
  } else {
    expectOptionalEqual(["Delete 'throw'", "Disable the test" ],
      nsError.userInfo[NSLocalizedRecoveryOptionsErrorKey as NSObject] as? [String])
  }
  expectOptionalEqual(["Delete 'throw'", "Disable the test" ],
    nsError.localizedRecoveryOptions)

  // None of the operations above should affect the count
  if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
    expectEqual(countBefore, MySwiftCustomizedError.errorDescriptionCount)
  }

  // This one does affect the count.
  expectEqual("something went horribly wrong", error.localizedDescription)

  // Check that we did get a call to errorDescription.
  if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
    expectEqual(countBefore+1, MySwiftCustomizedError.errorDescriptionCount)
  }
}

class MyNSError : NSError {  }

ErrorBridgingTests.test("NSError subclass identity") {
  let myNSError: Error = MyNSError(domain: "MyNSError", code: 0, userInfo: [:])
  let nsError = myNSError as NSError
  expectTrue(type(of: nsError) == MyNSError.self)
}

ErrorBridgingTests.test("Wrapped NSError identity") {
  let nsError = NSError(domain: NSCocoaErrorDomain,
                   code: NSFileNoSuchFileError,
                   userInfo: [
                     AnyHashable(NSFilePathErrorKey) : "/dev/null",
                     AnyHashable(NSStringEncodingErrorKey): /*ASCII=*/1,
                   ])

  let error: Error = nsError
  let nsError2: NSError = error as NSError
  expectTrue(nsError === nsError2)

  // Extracting the NSError via the runtime.
  let cocoaErrorAny: Any = error as! CocoaError
  let nsError3: NSError = cocoaErrorAny as! NSError
  expectTrue(nsError === nsError3)

  if let cocoaErrorAny2: Any = error as? CocoaError {
    let nsError4: NSError = cocoaErrorAny2 as! NSError
    expectTrue(nsError === nsError4)
  } else {
    expectUnreachable()
  }

  // Extracting the NSError via direct call.
  let cocoaError = error as! CocoaError
  let nsError5: NSError = cocoaError as NSError
  expectTrue(nsError === nsError5)

  if let cocoaError2 = error as? CocoaError {
    let nsError6: NSError = cocoaError as NSError
    expectTrue(nsError === nsError6)
  } else {
    expectUnreachable()
  }
}

extension Error {
	func asNSError() -> NSError {
		return self as NSError
	}
}

func unconditionalCast<T>(_ x: Any, to: T.Type) -> T {
  return x as! T
}

func conditionalCast<T>(_ x: Any, to: T.Type) -> T? {
  return x as? T
}

// SR-1562
ErrorBridgingTests.test("Error archetype identity") {
  let myError = NSError(domain: "myErrorDomain", code: 0,
                        userInfo: [ AnyHashable("one") : 1 ])
  expectTrue(myError === myError.asNSError())

  expectTrue(unconditionalCast(myError, to: Error.self) as NSError
     === myError)
  expectTrue(conditionalCast(myError, to: Error.self)! as NSError
     === myError)

  let nsError = NSError(domain: NSCocoaErrorDomain,
                        code: NSFileNoSuchFileError,
                        userInfo: [
                          AnyHashable(NSFilePathErrorKey) : "/dev/null",
                          AnyHashable(NSStringEncodingErrorKey): /*ASCII=*/1,
                        ])
  let cocoaError = nsError as Error as! CocoaError
  expectTrue(cocoaError.asNSError() === nsError)
  expectTrue(unconditionalCast(cocoaError, to: Error.self) as NSError
    === nsError)
  expectTrue(conditionalCast(cocoaError, to: Error.self)! as NSError
    === nsError)
}

runAllTests()
