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

#if LWIP_VERSION_MAJOR < 2
#define LWIP_DNS_FOUND_CALLBACK_TYPE    dns_found_callback
#endif // LWIP_VERSION_MAJOR < 2
#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
