// 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 struct NSPropertyListMutabilityOptions : OptionSet {
    public let rawValue : UInt
    public init(rawValue: UInt) { self.rawValue = rawValue }
    
    static let Immutable = NSPropertyListMutabilityOptions(rawValue: 0)
    static let MutableContainers = NSPropertyListMutabilityOptions(rawValue: 1)
    static let MutableContainersAndLeaves = NSPropertyListMutabilityOptions(rawValue: 2)
}

public enum NSPropertyListFormat : UInt {
    
    case OpenStepFormat = 1
    case XMLFormat_v1_0 = 100
    case BinaryFormat_v1_0 = 200
}

#if os(OSX) || os(iOS)
let kCFPropertyListOpenStepFormat = CFPropertyListFormat.openStepFormat
let kCFPropertyListXMLFormat_v1_0 = CFPropertyListFormat.xmlFormat_v1_0
let kCFPropertyListBinaryFormat_v1_0 = CFPropertyListFormat.binaryFormat_v1_0
#endif

public typealias NSPropertyListReadOptions = NSPropertyListMutabilityOptions
public typealias NSPropertyListWriteOptions = Int

public class NSPropertyListSerialization : NSObject {

    public class func propertyList(_ plist: AnyObject, isValidForFormat format: NSPropertyListFormat) -> Bool {
#if os(OSX) || os(iOS)
        let fmt = CFPropertyListFormat(rawValue: CFIndex(format.rawValue))!
#else
        let fmt = CFPropertyListFormat(format.rawValue)
#endif
        return CFPropertyListIsValid(unsafeBitCast(plist, to: CFPropertyList.self), fmt)
    }
    
    public class func dataWithPropertyList(_ plist: AnyObject, format: NSPropertyListFormat, options opt: NSPropertyListWriteOptions) throws -> NSData {
        var error: Unmanaged<CFError>? = nil
        let result = withUnsafeMutablePointer(&error) { (outErr: UnsafeMutablePointer<Unmanaged<CFError>?>) -> CFData? in
#if os(OSX) || os(iOS)
            let fmt = CFPropertyListFormat(rawValue: CFIndex(format.rawValue))!
#else
            let fmt = CFPropertyListFormat(format.rawValue)
#endif
            let options = CFOptionFlags(opt)
            return CFPropertyListCreateData(kCFAllocatorSystemDefault, plist, fmt, options, outErr)
        }
        if let res = result {
            return res._nsObject
        } else {
            throw error!.takeRetainedValue()._nsObject
        }
    }
    
    /// - Experiment: Note that the return type of this function is different than on Darwin Foundation (Any instead of AnyObject). This is likely to change once we have a more complete story for bridging in place.
    public class func propertyListWithData(_ data: NSData, options opt: NSPropertyListReadOptions, format: UnsafeMutablePointer<NSPropertyListFormat>?) throws -> Any {
        var fmt = kCFPropertyListBinaryFormat_v1_0
        var error: Unmanaged<CFError>? = nil
        let decoded = withUnsafeMutablePointers(&fmt, &error) { (outFmt: UnsafeMutablePointer<CFPropertyListFormat>, outErr: UnsafeMutablePointer<Unmanaged<CFError>?>) -> NSObject? in
            return unsafeBitCast(CFPropertyListCreateWithData(kCFAllocatorSystemDefault, unsafeBitCast(data, to: CFData.self), CFOptionFlags(CFIndex(opt.rawValue)), outFmt, outErr), to: NSObject.self)
        }
#if os(OSX) || os(iOS)
        format?.pointee = NSPropertyListFormat(rawValue: UInt(fmt.rawValue))!
#else
        format?.pointee = NSPropertyListFormat(rawValue: UInt(fmt))!
#endif
        if let err = error {
            throw err.takeUnretainedValue()._nsObject
        } else {
            return _expensivePropertyListConversion(decoded!)
        }
    }
    
    internal class func propertyListWithStream(_ stream: CFReadStream, length streamLength: Int, options opt: NSPropertyListReadOptions, format: UnsafeMutablePointer <NSPropertyListFormat>?) throws -> Any {
        var fmt = kCFPropertyListBinaryFormat_v1_0
        var error: Unmanaged<CFError>? = nil
        let decoded = withUnsafeMutablePointers(&fmt, &error) { (outFmt: UnsafeMutablePointer<CFPropertyListFormat>, outErr: UnsafeMutablePointer<Unmanaged<CFError>?>) -> NSObject? in
            return unsafeBitCast(CFPropertyListCreateWithStream(kCFAllocatorSystemDefault, stream, streamLength, CFOptionFlags(CFIndex(opt.rawValue)), outFmt, outErr), to: NSObject.self)
        }
#if os(OSX) || os(iOS)
        format?.pointee = NSPropertyListFormat(rawValue: UInt(fmt.rawValue))!
#else
        format?.pointee = NSPropertyListFormat(rawValue: UInt(fmt))!
#endif
        if let err = error {
            throw err.takeUnretainedValue()._nsObject
        } else {
            return _expensivePropertyListConversion(decoded!)
        }
    }
}

// Until we have proper bridging support, we will have to recursively convert NS/CFTypes to Swift types when we return them to callers. Otherwise, they may expect to treat them as Swift types and it will fail. Obviously this will cause a problem if they treat them as NS types, but we'll live with that for now.
internal func _expensivePropertyListConversion(_ input : AnyObject) -> Any {
    if let dict = input as? NSDictionary {
        var result : [String : Any] = [:]
        dict.enumerateKeysAndObjectsUsingBlock { key, value, _ in
            guard let k = key as? NSString else {
                fatalError("Non-string key in a property list")
            }
            
            result[k._swiftObject] = _expensivePropertyListConversion(value)
        }

        return result
    } else if let array = input as? NSArray {
        var result : [Any] = []
        array.enumerateObjectsUsingBlock { value, _, _ in
            result.append(_expensivePropertyListConversion(value))
        }

        return result
    } else if let str = input as? NSString {
        return str._swiftObject
    } else if let date = input as? NSDate {
        return date
    } else if let data = input as? NSData {
        return data
    } else if let number = input as? NSNumber {
        return number
    } else if input === kCFBooleanTrue {
        return true
    } else if input === kCFBooleanFalse {
        return false
    } else if input is __NSCFType && CFGetTypeID(input) == _CFKeyedArchiverUIDGetTypeID() {
        return input
    } else {
        fatalError("Attempt to convert a non-plist type \(input)")
    }
}

