// 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

open class Bundle: NSObject {
    private var _bundle : CFBundle!

    private static var _mainBundle : Bundle = {
        return Bundle(cfBundle: CFBundleGetMainBundle())
    }()
    
    open class var main: Bundle {
        get {
            return _mainBundle
        }
    }
    
    open class var allBundles: [Bundle] {
        NSUnimplemented()
    }

    
    internal init(cfBundle: CFBundle) {
        super.init()
        _bundle = cfBundle
    }
    
    public init?(path: String) {
        super.init()
        
        // TODO: We do not yet resolve symlinks, but we must for compatibility
        // let resolvedPath = path._nsObject.stringByResolvingSymlinksInPath
        let resolvedPath = path
        guard resolvedPath.length > 0 else {
            return nil
        }
        
        let url = URL(fileURLWithPath: resolvedPath)
        _bundle = CFBundleCreate(kCFAllocatorSystemDefault, unsafeBitCast(url, to: CFURL.self))
        if (_bundle == nil) {
            return nil
        }
    }
    
    public convenience init?(url: URL) {
        self.init(path: url.path)
    }
    
    public init(for aClass: AnyClass) { NSUnimplemented() }
    
    public init?(identifier: String) {
        super.init()
        
        guard let result = CFBundleGetBundleWithIdentifier(identifier._cfObject) else {
            return nil
        }
        
        _bundle = result
    }
    
    override open var description: String {
        return "\(String(describing: Bundle.self)) <\(bundleURL.path)> (\(isLoaded  ? "loaded" : "not yet loaded"))"
    }

    
    /* Methods for loading and unloading bundles. */
    open func load() -> Bool {
        return  CFBundleLoadExecutable(_bundle)
    }
    open var isLoaded: Bool {
        return CFBundleIsExecutableLoaded(_bundle)
    }
    @available(*,deprecated,message:"Not available on non-Darwin platforms")
    open func unload() -> Bool { NSUnsupported() }
    
    open func preflight() throws {
        var unmanagedError:Unmanaged<CFError>? = nil
        try withUnsafeMutablePointer(to: &unmanagedError) { (unmanagedCFError: UnsafeMutablePointer<Unmanaged<CFError>?>)  in
            CFBundlePreflightExecutable(_bundle, unmanagedCFError)
            if let error = unmanagedCFError.pointee {
                throw   error.takeRetainedValue()._nsObject
            }
        }
    }
    
    open func loadAndReturnError() throws {
        var unmanagedError:Unmanaged<CFError>? = nil
        try  withUnsafeMutablePointer(to: &unmanagedError) { (unmanagedCFError: UnsafeMutablePointer<Unmanaged<CFError>?>)  in
            CFBundleLoadExecutableAndReturnError(_bundle, unmanagedCFError)
            if let error = unmanagedCFError.pointee {
                let retainedValue = error.takeRetainedValue()
                throw  retainedValue._nsObject
            }
        }
    }

    
    /* Methods for locating various components of a bundle. */
    open var bundleURL: URL {
        return CFBundleCopyBundleURL(_bundle)._swiftObject
    }
    
    open var resourceURL: URL? {
        return CFBundleCopyResourcesDirectoryURL(_bundle)?._swiftObject
    }
    
    open var executableURL: URL? {
        return CFBundleCopyExecutableURL(_bundle)?._swiftObject
    }
    
    open func url(forAuxiliaryExecutable executableName: String) -> NSURL? {
        return CFBundleCopyAuxiliaryExecutableURL(_bundle, executableName._cfObject)?._nsObject
    }
    
    open var privateFrameworksURL: URL? {
        return CFBundleCopyPrivateFrameworksURL(_bundle)?._swiftObject
    }
    
    open var sharedFrameworksURL: URL? {
        return CFBundleCopySharedFrameworksURL(_bundle)?._swiftObject
    }
    
    open var sharedSupportURL: URL? {
        return CFBundleCopySharedSupportURL(_bundle)?._swiftObject
    }
    
    open var builtInPlugInsURL: URL? {
        return CFBundleCopyBuiltInPlugInsURL(_bundle)?._swiftObject
    }
    
    open var appStoreReceiptURL: URL? {
        // Always nil on this platform
        return nil
    }
    
    open var bundlePath: String {
        return bundleURL.path
    }
    
    open var resourcePath: String? {
        return resourceURL?.path
    }
    
    open var executablePath: String? {
        return executableURL?.path
    }
    
    open func path(forAuxiliaryExecutable executableName: String) -> String? {
        return url(forAuxiliaryExecutable: executableName)?.path
    }
    
    open var privateFrameworksPath: String? {
        return privateFrameworksURL?.path
    }
    
    open var sharedFrameworksPath: String? {
        return sharedFrameworksURL?.path
    }
    
    open var sharedSupportPath: String? {
        return sharedSupportURL?.path
    }
    
    open var builtInPlugInsPath: String? {
        return builtInPlugInsURL?.path
    }
    
    // -----------------------------------------------------------------------------------
    // MARK: - URL Resource Lookup - Class
    
    open class func url(forResource name: String?, withExtension ext: String?, subdirectory subpath: String?, in bundleURL: URL) -> URL? {
        // If both name and ext are nil/zero-length, return nil
        if (name == nil || name!.isEmpty) && (ext == nil || ext!.isEmpty) {
            return nil
        }
        
        return CFBundleCopyResourceURLInDirectory(bundleURL._cfObject, name?._cfObject, ext?._cfObject, subpath?._cfObject)._swiftObject
    }
    
    open class func urls(forResourcesWithExtension ext: String?, subdirectory subpath: String?, in bundleURL: NSURL) -> [NSURL]? {
        return CFBundleCopyResourceURLsOfTypeInDirectory(bundleURL._cfObject, ext?._cfObject, subpath?._cfObject)?._unsafeTypedBridge()
    }
    
    // -----------------------------------------------------------------------------------
    // MARK: - URL Resource Lookup - Instance

    open func url(forResource name: String?, withExtension ext: String?) -> URL? {
        return self.url(forResource: name, withExtension: ext, subdirectory: nil)
    }
    
    open func url(forResource name: String?, withExtension ext: String?, subdirectory subpath: String?) -> URL? {
        // If both name and ext are nil/zero-length, return nil
        if (name == nil || name!.isEmpty) && (ext == nil || ext!.isEmpty) {
            return nil
        }
        return CFBundleCopyResourceURL(_bundle, name?._cfObject, ext?._cfObject, subpath?._cfObject)?._swiftObject
    }
    
    open func url(forResource name: String?, withExtension ext: String?, subdirectory subpath: String?, localization localizationName: String?) -> URL? {
        // If both name and ext are nil/zero-length, return nil
        if (name == nil || name!.isEmpty) && (ext == nil || ext!.isEmpty) {
            return nil
        }

        return CFBundleCopyResourceURLForLocalization(_bundle, name?._cfObject, ext?._cfObject, subpath?._cfObject, localizationName?._cfObject)?._swiftObject
    }
    
    open func urls(forResourcesWithExtension ext: String?, subdirectory subpath: String?) -> [NSURL]? {
        return CFBundleCopyResourceURLsOfType(_bundle, ext?._cfObject, subpath?._cfObject)?._unsafeTypedBridge()
    }
    
    open func urls(forResourcesWithExtension ext: String?, subdirectory subpath: String?, localization localizationName: String?) -> [NSURL]? {
        return CFBundleCopyResourceURLsOfTypeForLocalization(_bundle, ext?._cfObject, subpath?._cfObject, localizationName?._cfObject)?._unsafeTypedBridge()
    }
    
    // -----------------------------------------------------------------------------------
    // MARK: - Path Resource Lookup - Class

    open class func path(forResource name: String?, ofType ext: String?, inDirectory bundlePath: String) -> String? {
        return Bundle.url(forResource: name, withExtension: ext, subdirectory: bundlePath, in: URL(fileURLWithPath: bundlePath))?.path ?? nil
    }
    
    open class func paths(forResourcesOfType ext: String?, inDirectory bundlePath: String) -> [String] {
        // Force-unwrap path, beacuse if the URL can't be turned into a path then something is wrong anyway
        return urls(forResourcesWithExtension: ext, subdirectory: bundlePath, in: NSURL(fileURLWithPath: bundlePath))?.map { $0.path! } ?? []
    }
    
    // -----------------------------------------------------------------------------------
    // MARK: - Path Resource Lookup - Instance

    open func path(forResource name: String?, ofType ext: String?) -> String? {
        return self.url(forResource: name, withExtension: ext, subdirectory: nil)?.path
    }
    
    open func path(forResource name: String?, ofType ext: String?, inDirectory subpath: String?) -> String? {
        return self.url(forResource: name, withExtension: ext, subdirectory: subpath)?.path
    }
    
    open func path(forResource name: String?, ofType ext: String?, inDirectory subpath: String?, forLocalization localizationName: String?) -> String? {
        return self.url(forResource: name, withExtension: ext, subdirectory: subpath, localization: localizationName)?.path
    }
    
    open func paths(forResourcesOfType ext: String?, inDirectory subpath: String?) -> [String] {
        // Force-unwrap path, beacuse if the URL can't be turned into a path then something is wrong anyway
        return self.urls(forResourcesWithExtension: ext, subdirectory: subpath)?.map { $0.path! } ?? []
    }
    
    open func paths(forResourcesOfType ext: String?, inDirectory subpath: String?, forLocalization localizationName: String?) -> [String] {
        // Force-unwrap path, beacuse if the URL can't be turned into a path then something is wrong anyway
        return self.urls(forResourcesWithExtension: ext, subdirectory: subpath, localization: localizationName)?.map { $0.path! } ?? []
    }
    
    // -----------------------------------------------------------------------------------
    // MARK: - Localized Strings
    
    open func localizedString(forKey key: String, value: String?, table tableName: String?) -> String {
        let localizedString = CFBundleCopyLocalizedString(_bundle, key._cfObject, value?._cfObject, tableName?._cfObject)!
        return localizedString._swiftObject
    }
    
    // -----------------------------------------------------------------------------------
    // MARK: - Other
    
    open var bundleIdentifier: String? {
        return CFBundleGetIdentifier(_bundle)?._swiftObject
    }
    
    open var infoDictionary: [String : Any]? {
        let cfDict: CFDictionary? = CFBundleGetInfoDictionary(_bundle)
        return _SwiftValue.fetch(cfDict) as? [String : Any]
    }
    
    open var localizedInfoDictionary: [String : Any]? {
        let cfDict: CFDictionary? = CFBundleGetLocalInfoDictionary(_bundle)
        return _SwiftValue.fetch(cfDict) as? [String : Any]
    }
    
    open func object(forInfoDictionaryKey key: String) -> Any? {
        if let localizedInfoDictionary = localizedInfoDictionary {
            return localizedInfoDictionary[key]
        } else {
            return infoDictionary?[key]
        }
    }
    
    open func classNamed(_ className: String) -> AnyClass? { NSUnimplemented() }
    open var principalClass: AnyClass? { NSUnimplemented() }
    open var preferredLocalizations: [String] {
        return Bundle.preferredLocalizations(from: localizations)
    }
    open var localizations: [String] {
        let cfLocalizations: CFArray? = CFBundleCopyBundleLocalizations(_bundle)
        let nsLocalizations = _SwiftValue.fetch(cfLocalizations) as? [Any]
        return nsLocalizations?.map { $0 as! String } ?? []
    }

    open var developmentLocalization: String? {
        let region = CFBundleGetDevelopmentRegion(_bundle)!
        return region._swiftObject
    }

    open class func preferredLocalizations(from localizationsArray: [String]) -> [String] {
        let cfLocalizations: CFArray? = CFBundleCopyPreferredLocalizationsFromArray(localizationsArray._cfObject)
        let nsLocalizations = _SwiftValue.fetch(cfLocalizations) as? [Any]
        return nsLocalizations?.map { $0 as! String } ?? []
    }
    
	open class func preferredLocalizations(from localizationsArray: [String], forPreferences preferencesArray: [String]?) -> [String] {
        let localizations = CFBundleCopyLocalizationsForPreferences(localizationsArray._cfObject, preferencesArray?._cfObject)!
        return localizations._swiftObject.map { return ($0 as! NSString)._swiftObject }
    }
	
	open var executableArchitectures: [NSNumber]? {
        let architectures = CFBundleCopyExecutableArchitectures(_bundle)!
        return architectures._swiftObject.map() { $0 as! NSNumber }
    }
}

