/*
 *
 *    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 the human-readable string formatting and
 *      parsing methods from class <tt>Inet::IPAddress</tt>.
 *
 */

#include <algorithm>
#include <limits>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <inet/IPAddress.h>
#include <lib/support/CodeUtils.h>

#if CHIP_SYSTEM_CONFIG_USE_POSIX_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
#include <arpa/inet.h>
#endif

namespace chip {
namespace Inet {

char * IPAddress::ToString(char * buf, uint32_t bufSize) const
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
#if INET_CONFIG_ENABLE_IPV4
    if (IsIPv4())
    {
        ip4_addr_t ip4_addr = ToIPv4();
        ip4addr_ntoa_r(&ip4_addr, buf, (int) bufSize);
    }
    else
#endif // INET_CONFIG_ENABLE_IPV4
    {
        ip6_addr_t ip6_addr = ToIPv6();
        ip6addr_ntoa_r(&ip6_addr, buf, (int) bufSize);
    }
#elif CHIP_SYSTEM_CONFIG_USE_SOCKETS
    // socklen_t is sometimes signed, sometimes not, so the only safe way to do
    // this is to promote everything to an unsigned type that's known to be big
    // enough for everything, then cast back to uint32_t after taking the min.
    bufSize = static_cast<uint32_t>(
        std::min(static_cast<uintmax_t>(std::numeric_limits<socklen_t>::max()), static_cast<uintmax_t>(bufSize)));
#if INET_CONFIG_ENABLE_IPV4
    if (IsIPv4())
    {
        const void * addr = &Addr[3];
        const char * s    = inet_ntop(AF_INET, addr, buf, static_cast<socklen_t>(bufSize));
        // This cast is safe because |s| points into |buf| which is not const.
        buf = const_cast<char *>(s);
    }
    else
#endif // INET_CONFIG_ENABLE_IPV4
    {
        const void * addr = &Addr[0];
        const char * s    = inet_ntop(AF_INET6, addr, buf, static_cast<socklen_t>(bufSize));
        // This cast is safe because |s| points into |buf| which is not const.
        buf = const_cast<char *>(s);
    }
#elif CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    otIp6Address addr = ToIPv6();
    otIp6AddressToString(&addr, buf, static_cast<uint16_t>(bufSize));
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP

    return buf;
}

bool IPAddress::FromString(const char * str, IPAddress & output)
{
#if INET_CONFIG_ENABLE_IPV4
    if (strchr(str, ':') == nullptr)
    {
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
        ip4_addr_t ipv4Addr;
        if (!ip4addr_aton(str, &ipv4Addr))
            return false;
#elif CHIP_SYSTEM_CONFIG_USE_SOCKETS
        struct in_addr ipv4Addr;
        if (inet_pton(AF_INET, str, &ipv4Addr) < 1)
            return false;
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
        output = IPAddress(ipv4Addr);
    }
    else
#endif // INET_CONFIG_ENABLE_IPV4
    {
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
        ip6_addr_t ipv6Addr;
        if (!ip6addr_aton(str, &ipv6Addr))
            return false;
#elif CHIP_SYSTEM_CONFIG_USE_SOCKETS
        struct in6_addr ipv6Addr;
        if (inet_pton(AF_INET6, str, &ipv6Addr) < 1)
            return false;
#elif CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
        otIp6Address ipv6Addr;
        if (OT_ERROR_NONE != otIp6AddressFromString(str, &ipv6Addr))
            return false;
#endif
        output = IPAddress(ipv6Addr);
    }

    return true;
}

bool IPAddress::FromString(const char * str, size_t strLen, IPAddress & output)
{
    bool res = false;

    if (strLen < INET6_ADDRSTRLEN)
    {
        char hostNameBuf[INET6_ADDRSTRLEN];
        memcpy(hostNameBuf, str, strLen);
        hostNameBuf[strLen] = 0;
        res                 = IPAddress::FromString(hostNameBuf, output);
    }

    return res;
}

bool IPAddress::FromString(const char * str, IPAddress & addrOutput, class InterfaceId & ifaceOutput)
{
    char * addrStr       = const_cast<char *>(str);
    char * addrPart      = nullptr;
    char * scopePart     = nullptr;
    char * strtokContext = nullptr;

    addrPart = strtok_r(addrStr, "%", &strtokContext);
    if (addrPart != nullptr)
    {
        scopePart = strtok_r(nullptr, "%", &strtokContext);
    }

    if (addrPart == nullptr || scopePart == nullptr)
    {
        ifaceOutput = Inet::InterfaceId();
        return Inet::IPAddress::FromString(addrStr, addrOutput);
    }

    CHIP_ERROR err = Inet::InterfaceId::InterfaceNameToId(scopePart, ifaceOutput);
    if (err != CHIP_NO_ERROR)
    {
        return false;
    }
    return Inet::IPAddress::FromString(addrPart, addrOutput);
}

} // namespace Inet
} // namespace chip
