/*
 *
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements DNSResolver, the object that abstracts
 *      Domain Name System (DNS) resolution in InetLayer.
 *
 */

#include <InetLayer/InetLayer.h>
#include <InetLayer/DNSResolver.h>
#include <InetLayer/InetLayerEvents.h>

#include <Weave/Support/CodeUtils.h>

#include <string.h>

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#include <lwip/init.h>
#include <lwip/dns.h>
#include <lwip/tcpip.h>

#ifndef LWIP_DNS_FOUND_CALLBACK_TYPE
#define LWIP_DNS_FOUND_CALLBACK_TYPE    dns_found_callback
#endif
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

namespace nl {
namespace Inet {

Weave::System::ObjectPool<DNSResolver, INET_CONFIG_NUM_DNS_RESOLVERS> DNSResolver::sPool;

/**
 *  This method revolves a host name into a list of IP addresses.
 *
 *  @note
 *     Even if the operation completes successfully,
 *     the result might be a zero-length list of IP addresses.
 *     Most of the error generated are returned via the
 *     application callback.
 *
 *  @param[in]  hostName    A pointer to a C string representing the host name
 *                          to be queried.
 *  @param[in]  hostNameLen The string length of host name.
 *  @param[in]  maxAddrs    The maximum number of addresses to store in the DNS
 *                          table.
 *  @param[in]  options     An integer value controlling how host name address
 *                          resolution is performed.  Values are from the #DNSOptions
 *                          enumeration.
 *  @param[in]  addrArray   A pointer to the DNS table.
 *  @param[in]  onComplete  A pointer to the callback function when a DNS
 *                          request is complete.
 *  @param[in]  appState    A pointer to the application state to be passed to
 *                          onComplete when a DNS request is complete.
 *
 *  @retval INET_NO_ERROR                   if a DNS request is handled
 *                                          successfully.
 *
 *  @retval INET_ERROR_NOT_IMPLEMENTED      if DNS resolution is not enabled on
 *                                          the underlying platform.
 *
 *  @retval _other_                         if other POSIX network or OS error
 *                                          was returned by the underlying DNS
 *                                          resolver implementation.
 *
 */
INET_ERROR DNSResolver::Resolve(const char *hostName, uint16_t hostNameLen, uint8_t options,
        uint8_t maxAddrs, IPAddress *addrArray,
        DNSResolver::OnResolveCompleteFunct onComplete, void *appState)
{
    INET_ERROR res = INET_NO_ERROR;

#if !WEAVE_SYSTEM_CONFIG_USE_SOCKETS && !LWIP_DNS
    Release();
    return INET_ERROR_NOT_IMPLEMENTED;
#endif // !WEAVE_SYSTEM_CONFIG_USE_SOCKETS && !LWIP_DNS

    uint8_t addrFamilyOption = (options & kDNSOption_AddrFamily_Mask);
    uint8_t optionFlags = (options & kDNSOption_Flags_Mask);

    // Check that the supplied options are valid.
    if ((addrFamilyOption != kDNSOption_AddrFamily_Any &&
         addrFamilyOption != kDNSOption_AddrFamily_IPv4Only &&
         addrFamilyOption != kDNSOption_AddrFamily_IPv4Preferred &&
         addrFamilyOption != kDNSOption_AddrFamily_IPv6Only &&
         addrFamilyOption != kDNSOption_AddrFamily_IPv6Preferred) ||
        (optionFlags & ~kDNSOption_ValidFlags) != 0)
    {
        Release();
        return INET_ERROR_BAD_ARGS;
    }

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS || (WEAVE_SYSTEM_CONFIG_USE_LWIP && LWIP_DNS)

    // TODO: Eliminate the need for a local buffer when running on LwIP by changing
    // the LwIP DNS interface to support non-nul terminated strings.

    char hostNameBuf[NL_DNS_HOSTNAME_MAX_LEN + 1]; // DNS limits hostnames to 253 max characters.

    memcpy(hostNameBuf, hostName, hostNameLen);
    hostNameBuf[hostNameLen] = 0;

    AppState = appState;
    AddrArray = addrArray;
    MaxAddrs = maxAddrs;
    NumAddrs = 0;
    DNSOptions = options;
    OnComplete = onComplete;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5

    u8_t lwipAddrType;

#if INET_CONFIG_ENABLE_IPV4
    switch (addrFamilyOption)
    {
    case kDNSOption_AddrFamily_IPv4Only:
        lwipAddrType = LWIP_DNS_ADDRTYPE_IPV4;
        break;
    case kDNSOption_AddrFamily_Any:
    case kDNSOption_AddrFamily_IPv4Preferred:
        lwipAddrType = LWIP_DNS_ADDRTYPE_IPV4_IPV6;
        break;
    case kDNSOption_AddrFamily_IPv6Only:
        lwipAddrType = LWIP_DNS_ADDRTYPE_IPV6;
        break;
    case kDNSOption_AddrFamily_IPv6Preferred:
        lwipAddrType = LWIP_DNS_ADDRTYPE_IPV6_IPV4;
        break;
    default:
        WeaveDie();
    }
#else // INET_CONFIG_ENABLE_IPV4
    lwipAddrType = LWIP_DNS_ADDRTYPE_IPV6;
#endif // INET_CONFIG_ENABLE_IPV4

#else // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR < 5

#if INET_CONFIG_ENABLE_IPV4
    if (addrFamilyOption == kDNSOption_AddrFamily_IPv6Only)
#endif
    {
        Release();
        return INET_ERROR_NOT_IMPLEMENTED;
    }

#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR < 5

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    ip_addr_t lwipAddr;
    LWIP_DNS_FOUND_CALLBACK_TYPE lwipCallback = reinterpret_cast<LWIP_DNS_FOUND_CALLBACK_TYPE>(LwIPHandleResolveComplete);

    err_t lwipErr =
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
            dns_gethostbyname_addrtype(hostNameBuf, &lwipAddr, lwipCallback, this, lwipAddrType);
#else
            dns_gethostbyname(hostNameBuf, &lwipAddr, lwipCallback, this);
#endif

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

    if (lwipErr == ERR_OK)
    {
        Weave::System::Layer& lSystemLayer = SystemLayer();

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
        AddrArray[0] = IPAddress::FromLwIPAddr(lwipAddr);
#else
        AddrArray[0] = IPAddress::FromIPv4(lwipAddr);
#endif
        NumAddrs = 1;

        lSystemLayer.PostEvent(*this, kInetEvent_DNSResolveComplete, 0);
    }
    else if (lwipErr != ERR_INPROGRESS)
    {
        res = Weave::System::MapErrorLwIP(lwipErr);
        Release();
    }

    return res;

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    struct addrinfo gaiHints;
    struct addrinfo * gaiResults = NULL;
    int gaiReturnCode;

    // Configure the hints argument for getaddrinfo()
    InitAddrInfoHints(gaiHints);

    // Call getaddrinfo() to perform the name resolution.
    gaiReturnCode = getaddrinfo(hostNameBuf, NULL, &gaiHints, &gaiResults);

    // Process the return code and results list returned by getaddrinfo(). If the call
    // was successful this will copy the resultant addresses into the caller's array.
    res = ProcessGetAddrInfoResult(gaiReturnCode, gaiResults);

    // Invoke the caller's completion function.
    onComplete(appState, res, NumAddrs, addrArray);

    // Release DNSResolver object.
    Release();

    return INET_NO_ERROR;

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS || (WEAVE_SYSTEM_CONFIG_USE_LWIP && LWIP_DNS)
}


/**
 *  This method cancels DNS requests that are in progress.
 *
 *  @retval INET_NO_ERROR.
 *
 */
INET_ERROR DNSResolver::Cancel()
{
#if WEAVE_SYSTEM_CONFIG_USE_LWIP

    // NOTE: LwIP does not support canceling DNS requests that are in progress.  As a consequence,
    // we can't release the DNSResolver object until LwIP calls us back (because LwIP retains a
    // pointer to the DNSResolver object while the request is active).  However, now that the
    // application has called Cancel() we have to make sure to NOT call their OnComplete function
    // when the request completes.
    //
    // To ensure the right thing happens, we NULL the OnComplete pointer here, which signals the
    // code in HandleResolveComplete() and LwIPHandleResolveComplete() to not interact with the
    // application's state data (AddrArray) and to not call the application's callback. This has
    // to happen with the LwIP lock held, since LwIPHandleResolveComplete() runs on LwIP's thread.

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    // Signal that the request has been canceled by clearing the state of the resolver object.
    OnComplete = NULL;
    AddrArray = NULL;
    MaxAddrs = 0;
    NumAddrs = 0;

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
#if INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
    // NOTE: DNS lookups can be canceled only when using the asynchronous mode.

    InetLayer& inet = Layer();

    OnComplete = NULL;
    AppState = NULL;
    inet.mAsyncDNSResolver.Cancel(*this);

#endif // INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return INET_NO_ERROR;
}

#if WEAVE_SYSTEM_CONFIG_USE_LWIP

/**
 *  This method is called by InetLayer on success, failure, or timeout of a
 *  DNS request.
 *
 */
void DNSResolver::HandleResolveComplete()
{
    // Call the application's completion handler if the request hasn't been canceled.
    if (OnComplete != NULL)
        OnComplete(AppState, (NumAddrs > 0) ? INET_NO_ERROR : INET_ERROR_HOST_NOT_FOUND, NumAddrs, AddrArray);

    // Release the resolver object.
    Release();
}


/**
 *  This method is called by LwIP network stack on success, failure, or timeout
 *  of a DNS request.
 *
 *  @param[in]  name            A pointer to a NULL-terminated C string
 *                              representing the host name that is queried.
 *  @param[in]  ipaddr          A pointer to a list of resolved IP addresses.
 *  @param[in]  callback_arg    A pointer to the arguments that are passed to
 *                              the callback function.
 *
 */
#if LWIP_VERSION_MAJOR > 1
void DNSResolver::LwIPHandleResolveComplete(const char *name, const ip_addr_t *ipaddr, void *callback_arg)
#else // LWIP_VERSION_MAJOR <= 1
void DNSResolver::LwIPHandleResolveComplete(const char *name, ip_addr_t *ipaddr, void *callback_arg)
#endif // LWIP_VERSION_MAJOR <= 1
{
    DNSResolver *resolver = (DNSResolver *)callback_arg;

    if (resolver != NULL)
    {
        Weave::System::Layer& lSystemLayer = resolver->SystemLayer();

        // Copy the resolved address to the application supplied buffer, but only if the request hasn't been canceled.
        if (resolver->OnComplete != NULL && ipaddr != NULL)
        {
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
            resolver->AddrArray[0] = IPAddress::FromLwIPAddr(*ipaddr);
#else
            resolver->AddrArray[0] = IPAddress::FromIPv4(*ipaddr);
#endif
            resolver->NumAddrs = 1;
        }

        lSystemLayer.PostEvent(*resolver, kInetEvent_DNSResolveComplete, 0);
    }
}

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

void DNSResolver::InitAddrInfoHints(struct addrinfo & hints)
{
    uint8_t addrFamilyOption = (DNSOptions & kDNSOption_AddrFamily_Mask);

    memset(&hints, 0, sizeof(hints));
#if INET_CONFIG_ENABLE_IPV4
    if (addrFamilyOption == kDNSOption_AddrFamily_IPv4Only)
    {
        hints.ai_family = AF_INET;
    }
    else if (addrFamilyOption == kDNSOption_AddrFamily_IPv6Only)
    {
        hints.ai_family = AF_INET6;
    }
    else
    {
        hints.ai_family = AF_UNSPEC;
    }
#else // INET_CONFIG_ENABLE_IPV4
    hints.ai_family = AF_INET6;
#endif // INET_CONFIG_ENABLE_IPV4
    hints.ai_flags = AI_ADDRCONFIG;
}

INET_ERROR DNSResolver::ProcessGetAddrInfoResult(int returnCode, struct addrinfo * results)
{
    INET_ERROR err = INET_NO_ERROR;

    // If getaddrinfo() succeeded, copy addresses in the returned addrinfo structures into the
    // application's output array...
    if (returnCode == 0)
    {
        NumAddrs = 0;

#if INET_CONFIG_ENABLE_IPV4

        // Based on the address family option specified by the application, determine which
        // types of addresses should be returned and the order in which they should appear.
        uint8_t addrFamilyOption = (DNSOptions & kDNSOption_AddrFamily_Mask);
        int primaryFamily, secondaryFamily;
        switch (addrFamilyOption)
        {
        case kDNSOption_AddrFamily_Any:
            primaryFamily = AF_UNSPEC;
            secondaryFamily = AF_UNSPEC;
            break;
        case kDNSOption_AddrFamily_IPv4Only:
            primaryFamily = AF_INET;
            secondaryFamily = AF_UNSPEC;
            break;
        case kDNSOption_AddrFamily_IPv4Preferred:
            primaryFamily = AF_INET;
            secondaryFamily = AF_INET6;
            break;
        case kDNSOption_AddrFamily_IPv6Only:
            primaryFamily = AF_INET6;
            secondaryFamily = AF_UNSPEC;
            break;
        case kDNSOption_AddrFamily_IPv6Preferred:
            primaryFamily = AF_INET6;
            secondaryFamily = AF_INET;
            break;
        default:
            WeaveDie();
        }

        // Determine the number of addresses of each family present in the results.
        // In the case of the secondary address family, only count these if they are
        // to be returned in the results.
        uint8_t numPrimaryAddrs = CountAddresses(primaryFamily, results);
        uint8_t numSecondaryAddrs = (secondaryFamily != AF_UNSPEC) ? CountAddresses(secondaryFamily, results) : 0;
        uint8_t numAddrs = numPrimaryAddrs + numSecondaryAddrs;

        // If the total number of addresses to be returned exceeds the application
        // specified max, ensure that at least 1 address from the secondary family
        // appears in the result (unless of course there are no such addresses or
        // the max is set to 1).
        // This ensures the application will try at least one secondary address
        // when attempting to communicate with the host.
        if (numAddrs > MaxAddrs && MaxAddrs > 1 && numPrimaryAddrs > 0 && numSecondaryAddrs > 0)
        {
            numPrimaryAddrs = ::nl::Weave::min(numPrimaryAddrs, (uint8_t)(MaxAddrs - 1));
        }

        // Copy the primary addresses into the beginning of the application's output array,
        // up to the limit determined above.
        CopyAddresses(primaryFamily, numPrimaryAddrs, results);

        // If secondary addresses are being returned, copy them into the output array after
        // the primary addresses.
        if (numSecondaryAddrs != 0)
        {
            CopyAddresses(secondaryFamily, numSecondaryAddrs, results);
        }

#else // INET_CONFIG_ENABLE_IPV4

        // Copy IPv6 addresses into the application's output array.
        CopyAddresses(AF_INET6, UINT8_MAX, results);

#endif // INET_CONFIG_ENABLE_IPV4

        // If in the end no addresses were returned, treat this as a "host not found" error.
        if (NumAddrs == 0)
        {
            err = INET_ERROR_HOST_NOT_FOUND;
        }
    }

    // Otherwise, getaddrinfo() failed, so translate the return code to an appropriate
    // Inet error...
    else
    {
        switch (returnCode)
        {
        case EAI_NONAME:
        case EAI_NODATA:
        case EAI_ADDRFAMILY:
            // Each of these errors is translated to "host not found" for simplicity at the
            // application layer. On most systems, the errors have the following meanings:
            //    EAI_NONAME is returned when there are no DNS records for the requested host name.
            //    EAI_NODATA is returned when there are no host records (A or AAAA) for the requested
            //      name, but other records do exist (e.g. MX or TXT).
            //    EAI_ADDRFAMILY is returned when a text-form address is given as the name, but its
            //      address family (IPv4 or IPv6) does not match the value specified in hints.ai_family.
            err = INET_ERROR_HOST_NOT_FOUND;
            break;
        case EAI_AGAIN:
            err = INET_ERROR_DNS_TRY_AGAIN;
            break;
        case EAI_SYSTEM:
            err = Weave::System::MapErrorPOSIX(errno);
            break;
        default:
            err = INET_ERROR_DNS_NO_RECOVERY;
            break;
        }
    }

    // Free the results structure.
    if (results != NULL)
        freeaddrinfo(results);

    return err;
}

void DNSResolver::CopyAddresses(int family, uint8_t count, const struct addrinfo * addrs)
{
    for (const struct addrinfo *addr = addrs;
         addr != NULL && NumAddrs < MaxAddrs && count > 0;
         addr = addr->ai_next)
    {
        if (family == AF_UNSPEC || addr->ai_addr->sa_family == family)
        {
            AddrArray[NumAddrs++] = IPAddress::FromSockAddr(*addr->ai_addr);
            count--;
        }
    }
}

uint8_t DNSResolver::CountAddresses(int family, const struct addrinfo * addrs)
{
    uint8_t count = 0;

    for (const struct addrinfo *addr = addrs;
         addr != NULL && count < UINT8_MAX;
         addr = addr->ai_next)
    {
        if (family == AF_UNSPEC || addr->ai_addr->sa_family == family)
        {
            count++;
        }
    }

    return count;
}

#if INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

void DNSResolver::HandleAsyncResolveComplete(void)
{
    // Copy the resolved address to the application supplied buffer, but only if the request hasn't been canceled.
    if (OnComplete && mState != kState_Canceled)
    {
        OnComplete(AppState, asyncDNSResolveResult, NumAddrs, AddrArray);
    }

    Release();
}
#endif // INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

} // namespace Inet
} // namespace nl
