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


import CoreFoundation

public let NSCocoaErrorDomain: String = "NSCocoaErrorDomain"

public let NSPOSIXErrorDomain: String = "NSPOSIXErrorDomain"
public let NSOSStatusErrorDomain: String = "NSOSStatusErrorDomain"
public let NSMachErrorDomain: String = "NSMachErrorDomain"

public let NSUnderlyingErrorKey: String = "NSUnderlyingError"

public let NSLocalizedDescriptionKey: String = "NSLocalizedDescription"
public let NSLocalizedFailureReasonErrorKey: String = "NSLocalizedFailureReason"
public let NSLocalizedRecoverySuggestionErrorKey: String = "NSLocalizedRecoverySuggestion"
public let NSLocalizedRecoveryOptionsErrorKey: String = "NSLocalizedRecoveryOptions"
public let NSRecoveryAttempterErrorKey: String = "NSRecoveryAttempter"
public let NSHelpAnchorErrorKey: String = "NSHelpAnchor"

public let NSStringEncodingErrorKey: String = "NSStringEncodingErrorKey"
public let NSURLErrorKey: String = "NSURL"
public let NSFilePathErrorKey: String = "NSFilePathErrorKey"


public class NSError : NSObject, NSCopying, NSSecureCoding, NSCoding {
    typealias CFType = CFError
    
    internal var _cfObject: CFType {
        return CFErrorCreate(kCFAllocatorSystemDefault, domain._cfObject, code, nil)
    }
    
    // ErrorType forbids this being internal
    public var _domain: String
    public var _code: Int
    /// - Experiment: This is a draft API currently under consideration for official import into Foundation
    /// - Note: This API differs from Darwin because it uses [String : Any] as a type instead of [String : AnyObject]. This allows the use of Swift value types.
    private var _userInfo: [String : Any]?
    
    /// - Experiment: This is a draft API currently under consideration for official import into Foundation
    /// - Note: This API differs from Darwin because it uses [String : Any] as a type instead of [String : AnyObject]. This allows the use of Swift value types.
    public init(domain: String, code: Int, userInfo dict: [String : Any]?) {
        _domain = domain
        _code = code
        _userInfo = dict
    }
    
    public required init?(coder aDecoder: NSCoder) {
        if aDecoder.allowsKeyedCoding {
            _code = aDecoder.decodeIntegerForKey("NSCode")
            _domain = aDecoder.decodeObjectOfClass(NSString.self, forKey: "NSDomain")!._swiftObject
            if let info = aDecoder.decodeObjectOfClasses([NSSet.self, NSDictionary.self, NSArray.self, NSString.self, NSNumber.self, NSData.self, NSURL.self], forKey: "NSUserInfo") as? NSDictionary {
                var filteredUserInfo = [String : Any]()
                // user info must be filtered so that the keys are all strings
                info.enumerateKeysAndObjectsUsingBlock() {
                    if let key = $0.0 as? NSString {
                        filteredUserInfo[key._swiftObject] = $0.1
                    }
                }
                _userInfo = filteredUserInfo
            }
        } else {
            var codeValue: Int32 = 0
            aDecoder.decodeValueOfObjCType("i", at: &codeValue)
            _code = Int(codeValue)
            _domain = (aDecoder.decodeObject() as? NSString)!._swiftObject
            if let info = aDecoder.decodeObject() as? NSDictionary {
                var filteredUserInfo = [String : Any]()
                // user info must be filtered so that the keys are all strings
                info.enumerateKeysAndObjectsUsingBlock() {
                    if let key = $0.0 as? NSString {
                        filteredUserInfo[key._swiftObject] = $0.1
                    }
                }
                _userInfo = filteredUserInfo
            }
        }
    }
    
    public static func supportsSecureCoding() -> Bool {
        return true
    }
    
    public func encodeWithCoder(_ aCoder: NSCoder) {
        if aCoder.allowsKeyedCoding {
            aCoder.encodeObject(_domain.bridge(), forKey: "NSDomain")
            aCoder.encodeInt(Int32(_code), forKey: "NSCode")
            aCoder.encodeObject(_userInfo?.bridge(), forKey: "NSUserInfo")
        } else {
            var codeValue: Int32 = Int32(self._code)
            aCoder.encodeValueOfObjCType("i", at: &codeValue)
            aCoder.encodeObject(self._domain.bridge())
            aCoder.encodeObject(self._userInfo?.bridge())
        }
    }
    
    public override func copy() -> AnyObject {
        return copyWithZone(nil)
    }
    
    public func copyWithZone(_ zone: NSZone) -> AnyObject {
        return self
    }
    
    public var domain: String {
        return _domain
    }
    
    public var code: Int {
        return _code
    }

    /// - Experiment: This is a draft API currently under consideration for official import into Foundation
    /// - Note: This API differs from Darwin because it uses [String : Any] as a type instead of [String : AnyObject]. This allows the use of Swift value types.
    public var userInfo: [String : Any] {
        if let info = _userInfo {
            return info
        } else {
            return Dictionary<String, Any>()
        }
    }
    
    public var localizedDescription: String {
        let desc = userInfo[NSLocalizedDescriptionKey] as? String
        
        return desc ?? "The operation could not be completed"
    }
    
    public var localizedFailureReason: String? {
        return userInfo[NSLocalizedFailureReasonErrorKey] as? String
    }
    
    public var localizedRecoverySuggestion: String? {
        return userInfo[NSLocalizedRecoverySuggestionErrorKey] as? String
    }

    public var localizedRecoveryOptions: [String]? {
        return userInfo[NSLocalizedRecoveryOptionsErrorKey] as? [String]
    }
    
    public var recoveryAttempter: AnyObject? {
        return userInfo[NSRecoveryAttempterErrorKey] as? AnyObject
    }
    
    public var helpAnchor: String? {
        return userInfo[NSHelpAnchorErrorKey] as? String
    }
    
    internal typealias NSErrorProvider = (error: NSError, key: String) -> AnyObject?
    internal static var userInfoProviders = [String: NSErrorProvider]()
    
    public class func setUserInfoValueProviderForDomain(_ errorDomain: String, provider: ((NSError, String) -> AnyObject?)?) {
        NSError.userInfoProviders[errorDomain] = provider
    }

    public class func userInfoValueProviderForDomain(_ errorDomain: String) -> ((NSError, String) -> AnyObject?)? {
        return NSError.userInfoProviders[errorDomain]
    }
}

extension NSError : ErrorProtocol { }

extension NSError : _CFBridgable { }
extension CFError : _NSBridgable {
    typealias NSType = NSError
    internal var _nsObject: NSType {
        let userInfo = CFErrorCopyUserInfo(self)._swiftObject
        var newUserInfo: [String: Any] = [:]
        for (key, value) in userInfo {
            if let key = key as? NSString {
                newUserInfo[key._swiftObject] = value
            }
        }

        return NSError(domain: CFErrorGetDomain(self)._swiftObject, code: CFErrorGetCode(self), userInfo: newUserInfo)
    }
}


public protocol _ObjectTypeBridgeableErrorType : ErrorProtocol {
    init?(_bridgedNSError: NSError)
}

public protocol __BridgedNSError : RawRepresentable, ErrorProtocol {
    static var __NSErrorDomain: String { get }
}

@warn_unused_result
public func ==<T: __BridgedNSError where T.RawValue: SignedInteger>(lhs: T, rhs: T) -> Bool {
    return lhs.rawValue.toIntMax() == rhs.rawValue.toIntMax()
}

public extension __BridgedNSError where RawValue: SignedInteger {
    public final var _domain: String { return Self.__NSErrorDomain }
    public final var _code: Int { return Int(rawValue.toIntMax()) }
    
    public init?(rawValue: RawValue) {
        self = unsafeBitCast(rawValue, to: Self.self)
    }
    
    public init?(_bridgedNSError: NSError) {
        if _bridgedNSError.domain != Self.__NSErrorDomain {
            return nil
        }
        
        self.init(rawValue: RawValue(IntMax(_bridgedNSError.code)))
    }
    
    public final var hashValue: Int { return _code }
}

@warn_unused_result
public func ==<T: __BridgedNSError where T.RawValue: UnsignedInteger>(lhs: T, rhs: T) -> Bool {
    return lhs.rawValue.toUIntMax() == rhs.rawValue.toUIntMax()
}

public extension __BridgedNSError where RawValue: UnsignedInteger {
    public final var _domain: String { return Self.__NSErrorDomain }
    public final var _code: Int {
        return Int(bitPattern: UInt(rawValue.toUIntMax()))
    }
    
    public init?(rawValue: RawValue) {
        self = unsafeBitCast(rawValue, to: Self.self)
    }
    
    public init?(_bridgedNSError: NSError) {
        if _bridgedNSError.domain != Self.__NSErrorDomain {
            return nil
        }
        
        self.init(rawValue: RawValue(UIntMax(UInt(_bridgedNSError.code))))
    }
    
    public final var hashValue: Int { return _code }
}

public protocol _BridgedNSError : __BridgedNSError, Hashable {
    // TODO: Was _NSErrorDomain, but that caused a module error.
    static var __NSErrorDomain: String { get }
}
