/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *
 *    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.h>
#include <DNSResolver.h>
#include <InetLayerEvents.h>

#include <support/CodeUtils.h>

#include <string.h>

#if CHIP_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 // CHIP_SYSTEM_CONFIG_USE_LWIP

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

namespace chip {
namespace Inet {

chip::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 !CHIP_SYSTEM_CONFIG_USE_SOCKETS && !LWIP_DNS
    Release();
    return INET_ERROR_NOT_IMPLEMENTED;
#endif // !CHIP_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 CHIP_SYSTEM_CONFIG_USE_SOCKETS || (CHIP_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 CHIP_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:
        chipDie();
    }
#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)
    {
        chip::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 = chip::System::MapErrorLwIP(lwipErr);
        Release();
    }

    return res;

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_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 // CHIP_SYSTEM_CONFIG_USE_SOCKETS
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || (CHIP_SYSTEM_CONFIG_USE_LWIP && LWIP_DNS)
}

/**
 *  This method cancels DNS requests that are in progress.
 *
 *  @retval INET_NO_ERROR.
 *
 */
INET_ERROR DNSResolver::Cancel()
{
#if CHIP_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 // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_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 // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    return INET_NO_ERROR;
}

#if CHIP_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)
    {
        chip::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 // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_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:
            chipDie();
        }

        // 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 = ::chip::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 = chip::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 // CHIP_SYSTEM_CONFIG_USE_SOCKETS

} // namespace Inet
} // namespace chip
