/*
 *
 *    Copyright (c) 2020 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 <vector>

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

#include <lib/support/CHIPMem.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/ScopedBuffer.h>

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#include <arpa/inet.h>
#include <sys/select.h>
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

using namespace chip;
using namespace chip::Inet;

System::LayerImpl gSystemLayer;

Inet::InetLayer gInet;

char gDefaultTapDeviceName[32];
bool gDone = false;

void InetFailError(int32_t err, const char * msg)
{
    if (err != CHIP_NO_ERROR)
    {
        LOG_ERR("%s: %s", msg, ErrorStr(err));
        exit(-1);
    }
}

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

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

void InitSystemLayer()
{
    gSystemLayer.Init();
}

void ShutdownSystemLayer()
{
    gSystemLayer.Shutdown();
}

void InitNetwork()
{
    void * lContext = nullptr;

    gInet.Init(gSystemLayer, lContext);
}

void ServiceEvents(struct ::timeval & aSleepTime)
{
    static bool printed = false;

    if (!printed)
    {
        {
            LOG_INF("CHIP node ready to service events");
            printed = true;
        }
    }
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    fd_set readFDs, writeFDs, exceptFDs;
    int numFDs = 0;

    FD_ZERO(&readFDs);
    FD_ZERO(&writeFDs);
    FD_ZERO(&exceptFDs);

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    if (gSystemLayer.IsInitialized())
    {
        gSystemLayer.PrepareSelect(numFDs, &readFDs, &writeFDs, &exceptFDs, aSleepTime);
    }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    if (gInet.State == InetLayer::kState_Initialized)
        gInet.PrepareSelect(numFDs, &readFDs, &writeFDs, &exceptFDs, aSleepTime);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    int selectRes = select(numFDs, &readFDs, &writeFDs, &exceptFDs, &aSleepTime);
    if (selectRes < 0)
    {
        LOG_INF("select failed: %s", ErrorStr(CHIP_ERROR_POSIX(errno)));
        return;
    }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    if (gSystemLayer.IsInitialized())
    {

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS

        gSystemLayer.HandleSelectResult(selectRes, &readFDs, &writeFDs, &exceptFDs);

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
    }

    if (gInet.State == InetLayer::kState_Initialized)
    {
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS

        gInet.HandleSelectResult(selectRes, &readFDs, &writeFDs, &exceptFDs);

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
    }
}

void ShutdownNetwork()
{
    gInet.Shutdown();
}

#define DUMP_BUF_LEN 80

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

    if (indexWidth < 4)
        indexWidth = 4;

    for (uint32_t i = 0; i < len; i += rowWidth)
    {
        char buf[DUMP_BUF_LEN];
        char * ptr           = buf;
        const char * buf_end = buf + DUMP_BUF_LEN;
        uint32_t rowEnd;
        uint32_t j;
        int result = snprintf(ptr, DUMP_BUF_LEN, "%s%0*X: ", prefix, indexWidth, i);
        if (result < 0 || result >= DUMP_BUF_LEN)
            goto print_line;

        ptr += result;
        rowEnd = i + rowWidth;

        j = i;
        for (; j < rowEnd && j < len; j++)
        {
            result = snprintf(ptr, buf_end - ptr, "%02X ", mem[j]);
            if (result < 0 || result >= buf_end - ptr)
                goto print_line;
            ptr += result;
        }

        for (; j < rowEnd; j++)
        {
            result = snprintf(ptr, buf_end - ptr, "   ");
            if (result < 0 || result >= buf_end - ptr)
                goto print_line;
            ptr += result;
        }

        for (j = i; j < rowEnd && j < len; j++)
        {
            if (isprint(static_cast<char>(mem[j])))
                result = snprintf(ptr, buf_end - ptr, "%c", mem[j]);
            else
                result = snprintf(ptr, buf_end - ptr, ".");
            if (result < 0 || result >= buf_end - ptr)
                goto print_line;
            ptr += result;
        }

    print_line:
        if (result < 0 || result >= buf_end - ptr)
        {
            LOG_ERR("Dump buffer overflow");
        }
        if (ptr > buf && ptr < buf + DUMP_BUF_LEN)
        {
            *ptr = '\0';
            LOG_INF(buf);
        }
    }
}

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

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