/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#include "ip_utils.h"
#include "sip_utils.h"
#include "string_utils.h"

#include <fmt/format.h>

extern "C" {
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>

#ifdef _WIN32
#define InetPtonA inet_pton
WINSOCK_API_LINKAGE INT WSAAPI InetPtonA(INT Family, LPCSTR pStringBuf, PVOID pAddr);
#else
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <sys/ioctl.h>
#endif
}

#ifndef HOST_NAME_MAX
#ifdef MAX_COMPUTERNAME_LENGTH
#define HOST_NAME_MAX MAX_COMPUTERNAME_LENGTH
#else
// Max 255 chars as per RFC 1035
#define HOST_NAME_MAX 255
#endif
#endif

namespace dhtnet {

namespace sip_utils {
std::string_view
sip_strerror(pj_status_t code)
{
    thread_local char err_msg[PJ_ERR_MSG_SIZE];
    return sip_utils::as_view(pj_strerror(code, err_msg, sizeof err_msg));
}
}

std::string
ip_utils::getHostname()
{
    char hostname[HOST_NAME_MAX];
    if (gethostname(hostname, HOST_NAME_MAX))
        return {};
    return hostname;
}

ip_utils::IpInterfaceAddress
ip_utils::getHostName()
{
    IpInterfaceAddress ret;
    char tempstr[INET_ADDRSTRLEN];
    const char* p = NULL;
#ifdef _WIN32
    struct hostent* h = NULL;
    struct sockaddr_in localAddr;
    memset(&localAddr, 0, sizeof(localAddr));
    char out[256];
    if (gethostname(out, sizeof(out)) == SOCKET_ERROR) {
        return {};
    }
    h = gethostbyname(out);
    if (h != NULL) {
        memcpy(&localAddr.sin_addr, h->h_addr_list[0], sizeof(localAddr.sin_addr));
        p = inet_ntop(AF_INET, &localAddr.sin_addr, tempstr, sizeof(tempstr));
        if (p) {
            ret.address = p;
        }
    }
#elif (defined(BSD) && BSD >= 199306) || defined(__FreeBSD_kernel__)
    struct ifaddrs* ifap;
    struct ifaddrs* ifa;
    if (getifaddrs(&ifap) != 0) {
        return {};
    }
    // Cycle through available interfaces.
    for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
        // Skip loopback, point-to-point and down interfaces.
        // except don't skip down interfaces if we're trying to get
        // a list of configurable interfaces.
        if ((ifa->ifa_flags & IFF_LOOPBACK) || (!(ifa->ifa_flags & IFF_UP))) {
            continue;
        }
        auto family = ifa->ifa_addr->sa_family;
        if (family == AF_INET) {
            void* addr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
            if (((struct sockaddr_in*)ifa->ifa_addr)->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
                continue;
            }
            ret.interface = ifa->ifa_name;
            p = inet_ntop(family, addr, tempstr, sizeof(tempstr));
            if (p) {
                ret.address = p;
            }
            break;
        }
    }
    freeifaddrs(ifap);
#else
    struct ifconf ifConf;
    struct ifreq ifReq;
    struct sockaddr_in localAddr;
    char szBuffer[MAX_INTERFACE * sizeof(struct ifreq)];
    int nResult;
    int localSock;
    memset(&ifConf, 0, sizeof(ifConf));
    memset(&ifReq, 0, sizeof(ifReq));
    memset(szBuffer, 0, sizeof(szBuffer));
    memset(&localAddr, 0, sizeof(localAddr));
    // Create an unbound datagram socket to do the SIOCGIFADDR ioctl on.
    localSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (localSock == INVALID_SOCKET) {
        return {};
    }
    /* Get the interface configuration information... */
    ifConf.ifc_len = sizeof(szBuffer);
    ifConf.ifc_buf = (caddr_t)szBuffer;
    nResult = ioctl(localSock, SIOCGIFCONF, &ifConf);
    if (nResult < 0) {
        close(localSock);
        return {};
    }
    unsigned int i;
    unsigned int j = 0;
    // Cycle through the list of interfaces looking for IP addresses.
    for (i = 0u; i < ifConf.ifc_len && j < MIN_INTERFACE;) {
        struct ifreq* pifReq = (struct ifreq*)((caddr_t)ifConf.ifc_req + i);
        i += sizeof *pifReq;
        // See if this is the sort of interface we want to deal with.
        memset(ifReq.ifr_name, 0, sizeof(ifReq.ifr_name));
        strncpy(ifReq.ifr_name, pifReq->ifr_name, sizeof(ifReq.ifr_name));
        ioctl(localSock, SIOCGIFFLAGS, &ifReq);
        // Skip loopback, point-to-point and down interfaces.
        // except don't skip down interfaces if we're trying to get
        // a list of configurable interfaces.
        if ((ifReq.ifr_flags & IFF_LOOPBACK) || (!(ifReq.ifr_flags & IFF_UP))) {
            continue;
        }
        if (pifReq->ifr_addr.sa_family == AF_INET) {
            if (((sockaddr_in*)&pifReq->ifr_addr)->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
                // We don't want the loopback interface. Go to the next one.
                continue;
            }
            ret.interface = pifReq->ifr_name;
            p = inet_ntop(pifReq->ifr_addr.sa_family,
                          &((sockaddr_in*)&pifReq->ifr_addr)->sin_addr,
                          tempstr,
                          sizeof(tempstr));
            if (p)
                ret.address = p;
        }
        j++; // Increment j if we found an address which is not loopback and is up.
    }
    close(localSock);
#endif
    return ret;
}

std::string
ip_utils::getGateway(std::string_view localHost, ip_utils::subnet_mask prefix)
{
    if (prefix == ip_utils::subnet_mask::prefix_32bit)
        return std::string(localHost);
    std::string defaultGw {};
    // Make a vector of each individual number in the ip address.
    std::vector<std::string_view> tokens = split_string(localHost, '.');
    // Build a gateway address from the individual ip components.
    for (unsigned i = 0; i <= (unsigned) prefix; i++)
        defaultGw = fmt::format("{:s}{:s}.", defaultGw, tokens[i]);
    for (unsigned i = (unsigned) ip_utils::subnet_mask::prefix_32bit;
         i > (unsigned) prefix + 1;
         i--)
        defaultGw += "0.";
    defaultGw += "1";
    return defaultGw;
}

IpAddr
ip_utils::getLocalGateway()
{
    char localHostBuf[INET_ADDRSTRLEN];
    auto hostInfo = ip_utils::getHostName();
    if (hostInfo.address.empty()) {
        // JAMI_WARN("Couldn't find local host");
        return {};
    } else {
        return IpAddr(ip_utils::getGateway(hostInfo.address, ip_utils::subnet_mask::prefix_24bit));
    }
}

std::vector<IpAddr>
ip_utils::getAddrList(std::string_view name, pj_uint16_t family)
{
    std::vector<IpAddr> ipList;
    if (name.empty())
        return ipList;
    if (IpAddr::isValid(name, family)) {
        ipList.emplace_back(name);
        return ipList;
    }

    static constexpr unsigned MAX_ADDR_NUM = 128;
    pj_addrinfo res[MAX_ADDR_NUM];
    unsigned addr_num = MAX_ADDR_NUM;
    const pj_str_t pjname(sip_utils::CONST_PJ_STR(name));
    auto status = pj_getaddrinfo(family, &pjname, &addr_num, res);
    if (status != PJ_SUCCESS) {
        // JAMI_ERR("Error resolving %.*s : %s",
        //          (int) name.size(),
        //          name.data(),
        //          sip_utils::sip_strerror(status).c_str());
        return ipList;
    }

    for (unsigned i = 0; i < addr_num; i++) {
        bool found = false;
        for (const auto& ip : ipList)
            if (!pj_sockaddr_cmp(&ip, &res[i].ai_addr)) {
                found = true;
                break;
            }
        if (!found)
            ipList.emplace_back(res[i].ai_addr);
    }

    return ipList;
}

bool
ip_utils::haveCommonAddr(const std::vector<IpAddr>& a, const std::vector<IpAddr>& b)
{
    for (const auto& i : a) {
        for (const auto& j : b) {
            if (i == j)
                return true;
        }
    }
    return false;
}

IpAddr
ip_utils::getLocalAddr(pj_uint16_t family)
{
    IpAddr ip_addr {};
    pj_status_t status = pj_gethostip(family, ip_addr.pjPtr());
    if (status == PJ_SUCCESS) {
        return ip_addr;
    }
    // JAMI_WARN("Could not get preferred address familly (%s)",
    //           (family == pj_AF_INET6()) ? "IPv6" : "IPv4");
    family = (family == pj_AF_INET()) ? pj_AF_INET6() : pj_AF_INET();
    status = pj_gethostip(family, ip_addr.pjPtr());
    if (status == PJ_SUCCESS) {
        return ip_addr;
    }
    // JAMI_ERR("Could not get local IP");
    return ip_addr;
}

IpAddr
ip_utils::getInterfaceAddr(const std::string& interface, pj_uint16_t family)
{
    if (interface == DEFAULT_INTERFACE)
        return getLocalAddr(family);

    IpAddr addr {};

#ifndef _WIN32
    const auto unix_family = family == pj_AF_INET() ? AF_INET : AF_INET6;

    int fd = socket(unix_family, SOCK_DGRAM, 0);
    if (fd < 0) {
        // JAMI_ERR("Could not open socket: %m");
        return addr;
    }

    if (unix_family == AF_INET6) {
        int val = family != pj_AF_UNSPEC();
        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &val, sizeof(val)) < 0) {
            // JAMI_ERR("Could not setsockopt: %m");
            close(fd);
            return addr;
        }
    }

    ifreq ifr;
    strncpy(ifr.ifr_name, interface.c_str(), sizeof ifr.ifr_name);
    // guarantee that ifr_name is NULL-terminated
    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';

    memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
    ifr.ifr_addr.sa_family = unix_family;

    ioctl(fd, SIOCGIFADDR, &ifr);
    close(fd);

    addr = ifr.ifr_addr;
    if (addr.isUnspecified())
        return getLocalAddr(addr.getFamily());
#else  // _WIN32
    struct addrinfo hints;
    struct addrinfo* result = NULL;
    struct sockaddr_in* sockaddr_ipv4;
    struct sockaddr_in6* sockaddr_ipv6;

    ZeroMemory(&hints, sizeof(hints));

    DWORD dwRetval = getaddrinfo(interface.c_str(), "0", &hints, &result);
    if (dwRetval != 0) {
        // JAMI_ERR("getaddrinfo failed with error: %lu", dwRetval);
        return addr;
    }

    switch (result->ai_family) {
        sockaddr_ipv4 = (struct sockaddr_in*) result->ai_addr;
        addr = sockaddr_ipv4->sin_addr;
        break;
    case AF_INET6:
        sockaddr_ipv6 = (struct sockaddr_in6*) result->ai_addr;
        addr = sockaddr_ipv6->sin6_addr;
        break;
    default:
        break;
    }

    if (addr.isUnspecified())
        return getLocalAddr(addr.getFamily());
#endif // !_WIN32

    return addr;
}

std::vector<std::string>
ip_utils::getAllIpInterfaceByName()
{
    std::vector<std::string> ifaceList;
    ifaceList.push_back("default");
#ifndef _WIN32
    static ifreq ifreqs[20];
    ifconf ifconf;

    ifconf.ifc_buf = (char*) (ifreqs);
    ifconf.ifc_len = sizeof(ifreqs);

    int sock = socket(AF_INET6, SOCK_STREAM, 0);

    if (sock >= 0) {
        if (ioctl(sock, SIOCGIFCONF, &ifconf) >= 0)
            for (unsigned i = 0; i < ifconf.ifc_len / sizeof(ifreq); ++i)
                ifaceList.push_back(std::string(ifreqs[i].ifr_name));

        close(sock);
    }

#else
    // JAMI_ERR("Not implemented yet. (iphlpapi.h problem)");
#endif
    return ifaceList;
}

std::vector<std::string>
ip_utils::getAllIpInterface()
{
    pj_sockaddr addrList[16];
    unsigned addrCnt = PJ_ARRAY_SIZE(addrList);

    std::vector<std::string> ifaceList;
    if (pj_enum_ip_interface(pj_AF_UNSPEC(), &addrCnt, addrList) == PJ_SUCCESS) {
        for (unsigned i = 0; i < addrCnt; i++) {
            char addr[PJ_INET6_ADDRSTRLEN];
            pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0);
            ifaceList.emplace_back(addr);
        }
    }

    return ifaceList;
}

std::vector<IpAddr>
ip_utils::getLocalNameservers()
{
    std::vector<IpAddr> res;
#if defined __ANDROID__ || defined _WIN32 || TARGET_OS_IPHONE
#ifdef _MSC_VER
#pragma message(__FILE__ "(" STR2(__LINE__) ") : -NOTE- " \
                                            "Not implemented")
#else
#warning "Not implemented"
#endif
#else
    if (not(_res.options & RES_INIT))
        res_init();
    res.insert(res.end(), _res.nsaddr_list, _res.nsaddr_list + _res.nscount);
#endif
    return res;
}

bool
IpAddr::isValid(std::string_view address, pj_uint16_t family)
{
    const pj_str_t pjstring(sip_utils::CONST_PJ_STR(address));
    pj_str_t ret_str;
    pj_uint16_t ret_port;
    int ret_family;
    auto status = pj_sockaddr_parse2(pj_AF_UNSPEC(), 0, &pjstring, &ret_str, &ret_port, &ret_family);
    if (status != PJ_SUCCESS || (family != pj_AF_UNSPEC() && ret_family != family))
        return false;

    char buf[PJ_INET6_ADDRSTRLEN];
    pj_str_t addr_with_null = {buf, 0};
    pj_strncpy_with_null(&addr_with_null, &ret_str, sizeof(buf));
    struct sockaddr sa;
    return inet_pton(ret_family == pj_AF_INET6() ? AF_INET6 : AF_INET, buf, &(sa.sa_data)) == 1;
}

bool
IpAddr::isUnspecified() const
{
    switch (addr.addr.sa_family) {
    case AF_INET:
        return IN_IS_ADDR_UNSPECIFIED(&addr.ipv4.sin_addr);
    case AF_INET6:
        return IN6_IS_ADDR_UNSPECIFIED(reinterpret_cast<const in6_addr*>(&addr.ipv6.sin6_addr));
    default:
        return true;
    }
}

bool
IpAddr::isLoopback() const
{
    switch (addr.addr.sa_family) {
    case AF_INET: {
        auto addr_host = ntohl(addr.ipv4.sin_addr.s_addr);
        uint8_t b1 = (uint8_t)(addr_host >> 24);
        return b1 == 127;
    }
    case AF_INET6:
        return IN6_IS_ADDR_LOOPBACK(reinterpret_cast<const in6_addr*>(&addr.ipv6.sin6_addr));
    default:
        return false;
    }
}

bool
IpAddr::isPrivate() const
{
    if (isLoopback()) {
        return true;
    }
    switch (addr.addr.sa_family) {
    case AF_INET: {
        auto addr_host = ntohl(addr.ipv4.sin_addr.s_addr);
        uint8_t b1, b2;
        b1 = (uint8_t)(addr_host >> 24);
        b2 = (uint8_t)((addr_host >> 16) & 0x0ff);
        // 10.x.y.z
        if (b1 == 10)
            return true;
        // 172.16.0.0 - 172.31.255.255
        if ((b1 == 172) && (b2 >= 16) && (b2 <= 31))
            return true;
        // 192.168.0.0 - 192.168.255.255
        if ((b1 == 192) && (b2 == 168))
            return true;
        return false;
    }
    case AF_INET6: {
        const pj_uint8_t* addr6 = reinterpret_cast<const pj_uint8_t*>(&addr.ipv6.sin6_addr);
        if (addr6[0] == 0xfc)
            return true;
        return false;
    }
    default:
        return false;
    }
}
} // namespace dhtnet
