/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2013-2018 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 constants, globals and interfaces common to
 *      and used by all CHP Inet layer library test applications and
 *      tools.
 *
 *      NOTE: These do not comprise a public part of the CHIP API and
 *            are subject to change without notice.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include "TestInetCommon.h"
#include "TestInetCommonOptions.h"

#include <errno.h>
#include <vector>

#include <inttypes.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include <lib/support/CHIPMem.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/ScopedBuffer.h>
#include <platform/PlatformManager.h>
#include <system/SystemClock.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/dns.h>
#if (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
#include <lwip/ip6_route_table.h>
#endif // (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
#include <lwip/init.h>
#include <lwip/netif.h>
#include <lwip/sys.h>
#include <lwip/tcpip.h>
#include <netif/etharp.h>

#if CHIP_TARGET_STYLE_UNIX

// TapAddrAutoconf and TapInterface are only needed for LwIP on
// sockets simulation in which a host tap/tun interface is used to
// proxy the LwIP stack onto a host native network interface.

#include "TapAddrAutoconf.h"
#include "TapInterface.h"
#endif // CHIP_TARGET_STYLE_UNIX
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

using namespace chip;
using namespace chip::Inet;

System::LayerImpl gSystemLayer;

Inet::UDPEndPointManagerImpl gUDP;
Inet::TCPEndPointManagerImpl gTCP;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
static sys_mbox_t * sLwIPEventQueue   = NULL;
static unsigned int sLwIPAcquireCount = 0;

static void AcquireLwIP(void)
{
    if (sLwIPAcquireCount++ == 0)
    {
        sys_mbox_new(sLwIPEventQueue, 100);
    }
}

static void ReleaseLwIP(void)
{
#if (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
    if (sLwIPAcquireCount > 0 && --sLwIPAcquireCount == 0)
    {
#if defined(INCLUDE_vTaskDelete) && INCLUDE_vTaskDelete
        // FreeRTOS need to delete the task not return from it.
        tcpip_finish(reinterpret_cast<tcpip_will_finish_fn>(vTaskDelete), NULL);
#else  // defined(INCLUDE_vTaskDelete) && INCLUDE_vTaskDelete
        tcpip_finish(NULL, NULL);
#endif // defined(INCLUDE_vTaskDelete) && INCLUDE_vTaskDelete
    }
#endif // (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
}

#if CHIP_TARGET_STYLE_UNIX
// TapAddrAutoconf and TapInterface are only needed for LwIP on
// sockets simulation in which a host tap/tun interface is used to
// proxy the LwIP stack onto a host native network interface.
// CollectTapAddresses() is only available on such targets.
static std::vector<TapInterface> sTapIFs;
#endif // CHIP_TARGET_STYLE_UNIX

static std::vector<struct netif> sNetIFs; // interface to filter

static bool NetworkIsReady();
static void OnLwIPInitComplete(void * arg);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

char gDefaultTapDeviceName[32];
bool gDone = false;

void InetFailError(CHIP_ERROR err, const char * msg)
{
    if (err != CHIP_NO_ERROR)
    {
        fprintf(stderr, "%s: %s\n", msg, ErrorStr(err));
        exit(-1);
    }
}

static void UseStdoutLineBuffering()
{
    // Set stdout to be line buffered with a buffer of 512 (will flush on new line
    // or when the buffer of 512 is exceeded).
#if CHIP_CONFIG_MEMORY_MGMT_MALLOC
    constexpr char * buf = nullptr;
#else
    static char buf[512];
#endif // CHIP_CONFIG_MEMORY_MGMT_MALLOC
    setvbuf(stdout, buf, _IOLBF, 512);
}

void InitTestInetCommon()
{
    chip::Platform::MemoryInit();
    UseStdoutLineBuffering();
}

void ShutdownTestInetCommon()
{
    chip::Platform::MemoryShutdown();
}

void InitSystemLayer()
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    AcquireLwIP();
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP

    gSystemLayer.Init();
}

void ShutdownSystemLayer()
{
    gSystemLayer.Shutdown();

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    ReleaseLwIP();
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

#if CHIP_SYSTEM_CONFIG_USE_LWIP
static void PrintNetworkState()
{
    char intfName[chip::Inet::InterfaceId::kMaxIfNameLength];

    for (size_t j = 0; j < gNetworkOptions.TapDeviceName.size(); j++)
    {
        struct netif * netIF = &(sNetIFs[j]);
#if CHIP_TARGET_STYLE_UNIX
        // TapAddrAutoconf and TapInterface are only needed for LwIP on
        // sockets simulation in which a host tap/tun interface is used to
        // proxy the LwIP stack onto a host native network interface.
        // CollectTapAddresses() is only available on such targets.

        TapInterface * tapIF = &(sTapIFs[j]);
#endif // CHIP_TARGET_STYLE_UNIX
        InterfaceId(netIF).GetInterfaceName(intfName, sizeof(intfName));

        printf("LwIP interface ready\n");
        printf("  Interface Name: %s\n", intfName);
        printf("  Tap Device: %s\n", gNetworkOptions.TapDeviceName[j]);
#if CHIP_TARGET_STYLE_UNIX
        // TapAddrAutoconf and TapInterface are only needed for LwIP on
        // sockets simulation in which a host tap/tun interface is used to
        // proxy the LwIP stack onto a host native network interface.
        // CollectTapAddresses() is only available on such targets.

        printf("  MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", tapIF->macAddr[0], tapIF->macAddr[1], tapIF->macAddr[2],
               tapIF->macAddr[3], tapIF->macAddr[4], tapIF->macAddr[5]);
#endif // CHIP_TARGET_STYLE_UNIX

#if INET_CONFIG_ENABLE_IPV4
        printf("  IPv4 Address: %s\n", ipaddr_ntoa(&(netIF->ip_addr)));
        printf("  IPv4 Mask: %s\n", ipaddr_ntoa(&(netIF->netmask)));
        printf("  IPv4 Gateway: %s\n", ipaddr_ntoa(&(netIF->gw)));
#endif // INET_CONFIG_ENABLE_IPV4
        for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++)
        {
            if (!ip6_addr_isany(netif_ip6_addr(netIF, i)))
            {
                printf("  IPv6 address: %s, 0x%02x\n", ip6addr_ntoa(netif_ip6_addr(netIF, i)), netif_ip6_addr_state(netIF, i));
            }
        }
    }
}
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

void InitNetwork()
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP

    // If an tap device name hasn't been specified, derive one from the IPv6 interface id.

    if (gNetworkOptions.TapDeviceName.empty())
    {
        for (size_t j = 0; j < gNetworkOptions.LocalIPv6Addr.size(); j++)
        {
            uint64_t iid    = gNetworkOptions.LocalIPv6Addr[j].InterfaceId();
            char * tap_name = (char *) chip::Platform::MemoryAlloc(sizeof(gDefaultTapDeviceName));
            assert(tap_name);
            snprintf(tap_name, sizeof(gDefaultTapDeviceName), "chip-dev-%x", static_cast<uint16_t>(iid));
            gNetworkOptions.TapDeviceName.push_back(tap_name);
        }
    }

#if CHIP_TARGET_STYLE_UNIX
    // TapAddrAutoconf and TapInterface are only needed for LwIP on
    // sockets simulation in which a host tap/tun interface is used to
    // proxy the LwIP stack onto a host native network interface.
    // CollectTapAddresses() is only available on such targets.

    sTapIFs.clear();
#endif // CHIP_TARGET_STYLE_UNIX
    sNetIFs.clear();

    for (size_t j = 0; j < gNetworkOptions.TapDeviceName.size(); j++)
    {
#if CHIP_TARGET_STYLE_UNIX
        // TapAddrAutoconf and TapInterface are only needed for LwIP on
        // sockets simulation in which a host tap/tun interface is used to
        // proxy the LwIP stack onto a host native network interface.
        // CollectTapAddresses() is only available on such targets.

        TapInterface tapIF;
        sTapIFs.push_back(tapIF);
#endif // CHIP_TARGET_STYLE_UNIX
        struct netif netIF;
        sNetIFs.push_back(netIF);
    }

#if CHIP_TARGET_STYLE_UNIX

    // TapAddrAutoconf and TapInterface are only needed for LwIP on
    // sockets simulation in which a host tap/tun interface is used to
    // proxy the LwIP stack onto a host native network interface.
    // CollectTapAddresses() is only available on such targets.

    err_t lwipErr;

    for (size_t j = 0; j < gNetworkOptions.TapDeviceName.size(); j++)
    {
        lwipErr = TapInterface_Init(&(sTapIFs[j]), gNetworkOptions.TapDeviceName[j], NULL);
        if (lwipErr != ERR_OK)
        {
            printf("Failed to initialize tap device %s: %s\n", gNetworkOptions.TapDeviceName[j],
                   ErrorStr(System::MapErrorLwIP(lwipErr)));
            exit(EXIT_FAILURE);
        }
    }
#endif // CHIP_TARGET_STYLE_UNIX
    tcpip_init(OnLwIPInitComplete, NULL);

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    for (size_t j = 0; j < gNetworkOptions.TapDeviceName.size(); j++)
    {
        std::vector<char *> addrsVec;

        addrsVec.clear();

#if CHIP_TARGET_STYLE_UNIX

        // TapAddrAutoconf and TapInterface are only needed for LwIP on
        // sockets simulation in which a host tap/tun interface is used to
        // proxy the LwIP stack onto a host native network interface.
        // CollectTapAddresses() is only available on such targets.
        if (gNetworkOptions.TapUseSystemConfig)
        {
            CollectTapAddresses(addrsVec, gNetworkOptions.TapDeviceName[j]);
        }
#endif // CHIP_TARGET_STYLE_UNIX
#if INET_CONFIG_ENABLE_IPV4

        IPAddress ip4Addr = (j < gNetworkOptions.LocalIPv4Addr.size()) ? gNetworkOptions.LocalIPv4Addr[j] : IPAddress::Any;
        for (size_t n = 0; n < addrsVec.size(); n++)
        {
            IPAddress auto_addr;
            if (IPAddress::FromString(addrsVec[n], auto_addr) && auto_addr.IsIPv4())
            {
                ip4Addr = auto_addr;
            }
        }

#if CHIP_TARGET_STYLE_UNIX
        // TapAddrAutoconf and TapInterface are only needed for LwIP on
        // sockets simulation in which a host tap/tun interface is used to
        // proxy the LwIP stack onto a host native network interface.
        // CollectTapAddresses() is only available on such targets.

        IPAddress ip4Gateway = (j < gNetworkOptions.IPv4GatewayAddr.size()) ? gNetworkOptions.IPv4GatewayAddr[j] : IPAddress::Any;

        {
            ip4_addr_t ip4AddrLwIP, ip4NetmaskLwIP, ip4GatewayLwIP;

            ip4AddrLwIP = ip4Addr.ToIPv4();
            IP4_ADDR(&ip4NetmaskLwIP, 255, 255, 255, 0);
            ip4GatewayLwIP = ip4Gateway.ToIPv4();
            netif_add(&(sNetIFs[j]), &ip4AddrLwIP, &ip4NetmaskLwIP, &ip4GatewayLwIP, &(sTapIFs[j]), TapInterface_SetupNetif,
                      tcpip_input);
        }
#endif // CHIP_TARGET_STYLE_UNIX

#endif // INET_CONFIG_ENABLE_IPV4

        netif_create_ip6_linklocal_address(&(sNetIFs[j]), 1);

#if (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
        if (j < gNetworkOptions.LocalIPv6Addr.size())
        {
            ip6_addr_t ip6addr = gNetworkOptions.LocalIPv6Addr[j].ToIPv6();
            s8_t index;
            netif_add_ip6_address_with_route(&(sNetIFs[j]), &ip6addr, 64, &index);
            // add ipv6 route for ipv6 address
            if (j < gNetworkOptions.IPv6GatewayAddr.size())
            {
                static ip6_addr_t br_ip6_addr = gNetworkOptions.IPv6GatewayAddr[j].ToIPv6();
                struct ip6_prefix ip6_prefix;
                ip6_prefix.addr       = Inet::IPAddress::Any.ToIPv6();
                ip6_prefix.prefix_len = 0;
                ip6_add_route_entry(&ip6_prefix, &sNetIFs[j], &br_ip6_addr, NULL);
            }
            if (index >= 0)
            {
                netif_ip6_addr_set_state(&(sNetIFs[j]), index, IP6_ADDR_PREFERRED);
            }
        }
        for (size_t n = 0; n < addrsVec.size(); n++)
        {
            IPAddress auto_addr;
            if (IPAddress::FromString(addrsVec[n], auto_addr) && !auto_addr.IsIPv4())
            {
                ip6_addr_t ip6addr = auto_addr.ToIPv6();
                s8_t index;
                if (auto_addr.IsIPv6LinkLocal())
                    continue; // skip over the LLA addresses, LwIP is aready adding those
                if (auto_addr.IsIPv6Multicast())
                    continue; // skip over the multicast addresses from host for now.
                netif_add_ip6_address_with_route(&(sNetIFs[j]), &ip6addr, 64, &index);
                if (index >= 0)
                {
                    netif_ip6_addr_set_state(&(sNetIFs[j]), index, IP6_ADDR_PREFERRED);
                }
            }
        }
#endif // (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)

        netif_set_up(&(sNetIFs[j]));
        netif_set_link_up(&(sNetIFs[j]));
    }

    netif_set_default(&(sNetIFs[0]));
    // UnLock LwIP stack

    UNLOCK_TCPIP_CORE();

    while (!NetworkIsReady())
    {
        constexpr uint32_t kSleepTimeMilliseconds = 100;
        ServiceEvents(kSleepTimeMilliseconds);
    }

    // FIXME: this is kinda nasty :(
    // Force new IP address to be ready, bypassing duplicate detection.

    for (size_t j = 0; j < gNetworkOptions.TapDeviceName.size(); j++)
    {
        if (j < gNetworkOptions.LocalIPv6Addr.size())
        {
            netif_ip6_addr_set_state(&(sNetIFs[j]), 2, 0x30);
        }
        else
        {
            netif_ip6_addr_set_state(&(sNetIFs[j]), 1, 0x30);
        }
    }

    PrintNetworkState();

    AcquireLwIP();

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    gTCP.Init(gSystemLayer);
    gUDP.Init(gSystemLayer);
}

void ServiceEvents(uint32_t aSleepTimeMilliseconds)
{
    static bool printed = false;

    if (!printed)
    {
#if CHIP_SYSTEM_CONFIG_USE_LWIP
        if (NetworkIsReady())
#endif
        {
            printf("CHIP node ready to service events\n");
            fflush(stdout);
            printed = true;
        }
    }

    // Start a timer (with a no-op callback) to ensure that WaitForEvents() does not block longer than aSleepTimeMilliseconds.
    gSystemLayer.StartTimer(
        System::Clock::Milliseconds32(aSleepTimeMilliseconds), [](System::Layer *, void *) -> void {}, nullptr);

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    gSystemLayer.PrepareEvents();
    gSystemLayer.WaitForEvents();
    gSystemLayer.HandleEvents();
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    if (gSystemLayer.IsInitialized())
    {
        static uint32_t sRemainingSystemLayerEventDelay = 0;

        if (sRemainingSystemLayerEventDelay == 0)
        {
            chip::DeviceLayer::PlatformMgr().RunEventLoop();
            sRemainingSystemLayerEventDelay = gNetworkOptions.EventDelay;
        }
        else
            sRemainingSystemLayerEventDelay--;

        gSystemLayer.HandlePlatformTimer();
    }
#if CHIP_TARGET_STYLE_UNIX
    // TapAddrAutoconf and TapInterface are only needed for LwIP on
    // sockets simulation in which a host tap/tun interface is used to
    // proxy the LwIP stack onto a host native network interface.
    // CollectTapAddresses() is only available on such targets.

    TapInterface_Select(&(sTapIFs[0]), &(sNetIFs[0]), aSleepTime, gNetworkOptions.TapDeviceName.size());
#endif // CHIP_TARGET_STYLE_UNIX
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

#if CHIP_SYSTEM_CONFIG_USE_LWIP
static bool NetworkIsReady()
{
    bool ready = true;

    for (size_t j = 0; j < gNetworkOptions.TapDeviceName.size(); j++)
    {
        for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++)
        {
            if (!ip6_addr_isany(netif_ip6_addr(&(sNetIFs[j]), i)) && ip6_addr_istentative(netif_ip6_addr_state(&(sNetIFs[j]), i)))
            {
                ready = false;
                break;
            }
        }
    }
    return ready;
}

static void OnLwIPInitComplete(void * arg)
{
    printf("Waiting for addresses assignment...\n");
}

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

void ShutdownNetwork()
{
    gTCP.ForEachEndPoint([](TCPEndPoint * lEndPoint) -> Loop {
        gTCP.ReleaseEndPoint(lEndPoint);
        return Loop::Continue;
    });
    gTCP.Shutdown();

    gUDP.ForEachEndPoint([](UDPEndPoint * lEndPoint) -> Loop {
        gUDP.ReleaseEndPoint(lEndPoint);
        return Loop::Continue;
    });
    gUDP.Shutdown();
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    ReleaseLwIP();
#endif
}

void DumpMemory(const uint8_t * mem, uint32_t len, const char * prefix, uint32_t rowWidth)
{
    int indexWidth = snprintf(nullptr, 0, "%" PRIX32, len);

    if (indexWidth < 4)
        indexWidth = 4;

    for (uint32_t i = 0; i < len; i += rowWidth)
    {
        printf("%s%0*" PRIX32 ": ", prefix, indexWidth, i);

        uint32_t rowEnd = i + rowWidth;

        uint32_t j = i;
        for (; j < rowEnd && j < len; j++)
            printf("%02X ", mem[j]);

        for (; j < rowEnd; j++)
            printf("   ");

        for (j = i; j < rowEnd && j < len; j++)
            if (isprint(static_cast<char>(mem[j])))
                printf("%c", mem[j]);
            else
                printf(".");

        printf("\n");
    }
}

void DumpMemory(const uint8_t * mem, uint32_t len, const char * prefix)
{
    const uint32_t kRowWidth = 16;

    DumpMemory(mem, len, prefix, kRowWidth);
}
