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


#if os(OSX) || os(iOS)
import Darwin
#elseif os(Linux)
import Glibc
#endif

import CoreFoundation

public class NSHost : NSObject {
    enum ResolveType {
        case Name
        case Address
        case Current
    }
    internal var _info: String?
    internal var _type: ResolveType
    internal var _resolved = false
    internal var _names = [String]()
    internal var _addresses = [String]()
    
    internal init(_ info: String?, _ type: ResolveType) {
        _info = info
        _type = type
    }
    
    static internal let current = NSHost(nil, .Current)
    
    public class func currentHost() -> NSHost {
        return NSHost.current
    }
    
    public convenience init(name: String?) {
        self.init(name, .Name)
    }
    
    public convenience init(address: String) {
        self.init(address, .Address)
    }
    
    public func isEqualToHost(_ aHost: NSHost) -> Bool {
        return false
    }
    
    internal func _resolveCurrent() {
        // TODO: cannot access getifaddrs here...
    }
    
    internal func _resolve() {
        if _resolved {
            return
        }
        if let info = _info {
            var flags: Int32 = 0
            switch (_type) {
            case .Name:
                flags = AI_PASSIVE | AI_CANONNAME
                break
            case .Address:
                flags = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST
                break
            case .Current:
                _resolveCurrent()
                return
            }
            var hints = addrinfo()
            hints.ai_family = PF_UNSPEC
            hints.ai_socktype = _CF_SOCK_STREAM()
            hints.ai_flags = flags
            
            var res0: UnsafeMutablePointer<addrinfo>? = nil
            let r = getaddrinfo(info, nil, &hints, &res0)
            if r != 0 {
                return
            }
            var res: UnsafeMutablePointer<addrinfo>? = res0
            while res != nil {
                let info = res!.pointee
                let family = info.ai_family
                if family != AF_INET && family != AF_INET6 {
                    res = info.ai_next
                    continue
                }
                let sa_len: socklen_t = socklen_t((family == AF_INET6) ? sizeof(sockaddr_in6) : sizeof(sockaddr_in))
                let lookupInfo = { (content: inout [String], flags: Int32) in
                    let hname = UnsafeMutablePointer<Int8>(allocatingCapacity: 1024)
                    if (getnameinfo(info.ai_addr, sa_len, hname, 1024, nil, 0, flags) == 0) {
                        content.append(String(hname))
                    }
                    hname.deinitialize()
                    hname.deallocateCapacity(1024)
                }
                lookupInfo(&_addresses, NI_NUMERICHOST)
                lookupInfo(&_names, NI_NAMEREQD)
                lookupInfo(&_names, NI_NOFQDN|NI_NAMEREQD)
                res = info.ai_next
            }
            
            freeaddrinfo(res0)
        }

    }
    
    public var name: String? {
        return names.first
    }
    
    public var names: [String] {
        _resolve()
        return _names
    }
    
    public var address: String? {
        return addresses.first
    }
    
    public var addresses: [String] {
        _resolve()
        return _addresses
    }
    
    public var localizedName: String? {
        return nil
    }
}

