// 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>(
  _ object: T
) -> T?
where T: NSObject {
  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: "https://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)
    expectNil(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, *) {
    expectNil(nsError.userInfo[NSLocalizedDescriptionKey as NSObject])
    expectNil(nsError.userInfo[NSLocalizedFailureReasonErrorKey as NSObject])
    expectNil(nsError.userInfo[NSLocalizedRecoverySuggestionErrorKey as NSObject])
    expectNil(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, *) {
    expectNil(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 ctx = UnsafeMutableRawPointer(bitPattern:0x1234567)
  let attempter: AnyObject
  if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
    expectNil(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: ctx)
  expectEqual(false, rd1.called)
  attempter.attemptRecovery(
    fromError: nsError,
    optionIndex: 0,
    delegate: rd1,
    didRecoverSelector: #selector(RecoveryDelegate.recover(success:contextInfo:)),
    contextInfo: ctx)
  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, *) {
    expectNil(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)
  }
}

enum DefaultCustomizedError1 : CustomNSError {
  case bad
  case worse
}

enum DefaultCustomizedError2 : Int, CustomNSError {
  case bad = 7
  case worse = 13
}

enum DefaultCustomizedError3 : UInt, CustomNSError {
  case bad = 9
  case worse = 115

  static var errorDomain: String {
    return "customized3"
  }
}

enum DefaultCustomizedParent {
    enum ChildError: CustomNSError {
        case foo
    }
}

ErrorBridgingTests.test("Default-customized via CustomNSError") {
  expectEqual(1, (DefaultCustomizedError1.worse as NSError).code)
  expectEqual(13, (DefaultCustomizedError2.worse as NSError).code)
  expectEqual(115, (DefaultCustomizedError3.worse as NSError).code)
  expectEqual("main.DefaultCustomizedError1", (DefaultCustomizedError1.worse as NSError).domain)
  expectEqual("customized3", (DefaultCustomizedError3.worse as NSError).domain)
  expectEqual("main.DefaultCustomizedParent.ChildError", (DefaultCustomizedParent.ChildError.foo as NSError).domain)
}

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()
