/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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
 *      Common command-line option handling code for test applications.
 *
 */

#include "TestInetCommonOptions.h"

#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <inet/InetFaultInjection.h>
#include <lib/support/CHIPFaultInjection.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPMemString.h>
#include <system/SystemFaultInjection.h>

using namespace chip;
using namespace chip::ArgParser;
using namespace chip::Inet;

// Global Variables

NetworkOptions gNetworkOptions;
FaultInjectionOptions gFaultInjectionOptions;

NetworkOptions::NetworkOptions()
{
    static OptionDef optionDefs[] = {
        { "local-addr", kArgumentRequired, 'a' },
        { "node-addr", kArgumentRequired, kToolCommonOpt_NodeAddr }, /* alias for local-addr */
#if CHIP_SYSTEM_CONFIG_USE_LWIP
        { "tap-device", kArgumentRequired, kToolCommonOpt_TapDevice },
        { "ipv4-gateway", kArgumentRequired, kToolCommonOpt_IPv4GatewayAddr },
        { "ipv6-gateway", kArgumentRequired, kToolCommonOpt_IPv6GatewayAddr },
        { "dns-server", kArgumentRequired, 'X' },
        { "debug-lwip", kNoArgument, kToolCommonOpt_DebugLwIP },
        { "event-delay", kArgumentRequired, kToolCommonOpt_EventDelay },
        { "tap-system-config", kNoArgument, kToolCommonOpt_TapInterfaceConfig },
#endif
        {}
    };
    OptionDefs = optionDefs;

    HelpGroupName = "NETWORK OPTIONS";

    OptionHelp = "  -a, --local-addr, --node-addr <ip-addr>\n"
                 "       Local address for the node.\n"
                 "\n"
#if CHIP_SYSTEM_CONFIG_USE_LWIP
                 "  --tap-device <tap-dev-name>\n"
                 "       TAP device name for LwIP hosted OS usage. Defaults to chip-dev-<node-id>.\n"
                 "\n"
                 "  --ipv4-gateway <ip-addr>\n"
                 "       Address of default IPv4 gateway.\n"
                 "\n"
                 "  --ipv6-gateway <ip-addr>\n"
                 "       Address of default IPv6 gateway.\n"
                 "\n"
                 "  -X, --dns-server <ip-addr>\n"
                 "       IPv4 address of local DNS server.\n"
                 "\n"
                 "  --debug-lwip\n"
                 "       Enable LwIP debug messages.\n"
                 "\n"
                 "  --event-delay <int>\n"
                 "       Delay event processing by specified number of iterations. Defaults to 0.\n"
                 "\n"
                 "  --tap-system-config\n"
                 "       Use configuration on each of the Linux TAP interfaces to configure LwIP's interfaces.\n"
                 "\n"
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
        ;

    // Defaults.
    LocalIPv4Addr.clear();
    LocalIPv6Addr.clear();

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    TapDeviceName.clear();
    LwIPDebugFlags = 0;
    EventDelay     = 0;
    IPv4GatewayAddr.clear();
    IPv6GatewayAddr.clear();
    DNSServerAddr      = Inet::IPAddress::Any;
    TapUseSystemConfig = false;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

bool NetworkOptions::HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    Inet::IPAddress localAddr;

    switch (id)
    {
    case 'a':
    case kToolCommonOpt_NodeAddr:
        if (!ParseIPAddress(arg, localAddr))
        {
            PrintArgError("%s: Invalid value specified for local IP address: %s\n", progName, arg);
            return false;
        }
#if INET_CONFIG_ENABLE_IPV4
        if (localAddr.IsIPv4())
        {
            LocalIPv4Addr.push_back(localAddr);
        }
        else
        {
            LocalIPv6Addr.push_back(localAddr);
        }
#else  // INET_CONFIG_ENABLE_IPV4
        LocalIPv6Addr.push_back(localAddr);
#endif // INET_CONFIG_ENABLE_IPV4
        break;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    case 'X':
        if (!ParseIPAddress(arg, DNSServerAddr))
        {
            PrintArgError("%s: Invalid value specified for DNS server address: %s\n", progName, arg);
            return false;
        }
        break;
    case kToolCommonOpt_TapDevice:
        TapDeviceName.push_back(arg);
        break;

    case kToolCommonOpt_IPv4GatewayAddr: {
        if (!ParseIPAddress(arg, localAddr) || !localAddr.IsIPv4())
        {
            PrintArgError("%s: Invalid value specified for IPv4 gateway address: %s\n", progName, arg);
            return false;
        }
        IPv4GatewayAddr.push_back(localAddr);
    }
    break;

    case kToolCommonOpt_IPv6GatewayAddr: {
        if (!ParseIPAddress(arg, localAddr))
        {
            PrintArgError("%s: Invalid value specified for IPv6 gateway address: %s\n", progName, arg);
            return false;
        }
        IPv6GatewayAddr.push_back(localAddr);
    }
    break;

    case kToolCommonOpt_DebugLwIP:
#if defined(LWIP_DEBUG)
#if CHIP_TARGET_STYLE_UNIX
        gLwIP_DebugFlags = (LWIP_DBG_ON | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_FRESH | LWIP_DBG_HALT);
#endif
#endif
        break;
    case kToolCommonOpt_EventDelay:
        if (!ParseInt(arg, EventDelay))
        {
            PrintArgError("%s: Invalid value specified for event delay: %s\n", progName, arg);
            return false;
        }
        break;

    case kToolCommonOpt_TapInterfaceConfig:
        TapUseSystemConfig = true;
        break;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

FaultInjectionOptions::FaultInjectionOptions()
{
    static OptionDef optionDefs[] = {
#if CHIP_CONFIG_TEST || CHIP_SYSTEM_CONFIG_TEST || INET_CONFIG_TEST
        { "faults", kArgumentRequired, kToolCommonOpt_FaultInjection },
        { "iterations", kArgumentRequired, kToolCommonOpt_FaultTestIterations },
        { "debug-resource-usage", kNoArgument, kToolCommonOpt_DebugResourceUsage },
        { "print-fault-counters", kNoArgument, kToolCommonOpt_PrintFaultCounters },
        { "extra-cleanup-time", kArgumentRequired, kToolCommonOpt_ExtraCleanupTime },
#endif
        {}
    };
    OptionDefs = optionDefs;

    HelpGroupName = "FAULT INJECTION OPTIONS";

    OptionHelp =
#if CHIP_CONFIG_TEST || CHIP_SYSTEM_CONFIG_TEST || INET_CONFIG_TEST
        "  --faults <fault-string>\n"
        "       Inject specified fault(s) into the operation of the tool at runtime.\n"
        "\n"
        "  --iterations <int>\n"
        "       Execute the program operation the given number of times\n"
        "\n"
        "  --debug-resource-usage\n"
        "       Print all stats counters before exiting.\n"
        "\n"
        "  --print-fault-counters\n"
        "       Print the fault-injection counters before exiting.\n"
        "\n"
        "  --extra-cleanup-time\n"
        "       Allow extra time before asserting resource leaks; this is useful when\n"
        "       running fault-injection tests to let the system free stale ExchangeContext\n"
        "       instances after RMP has exhausted all retransmission; a failed RMP transmission\n"
        "       should fail a normal happy-sequence test, but not necessarily a fault-injection test.\n"
        "       The value is in milliseconds; a common value is 10000.\n"
        "\n"
#endif
        "";

    // Defaults
    TestIterations       = 1;
    DebugResourceUsage   = false;
    PrintFaultCounters   = false;
    ExtraCleanupTimeMsec = 0;
}

#if defined(CHIP_WITH_NLFAULTINJECTION) && CHIP_WITH_NLFAULTINJECTION
bool FaultInjectionOptions::HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    using namespace nl::FaultInjection;

    GetManagerFn faultMgrFnTable[] = { Inet::FaultInjection::GetManager, System::FaultInjection::GetManager };
    size_t faultMgrFnTableLen      = sizeof(faultMgrFnTable) / sizeof(faultMgrFnTable[0]);

    switch (id)
    {
#if CHIP_CONFIG_TEST || CHIP_SYSTEM_CONFIG_TEST || INET_CONFIG_TEST
    case kToolCommonOpt_FaultInjection: {
        chip::Platform::ScopedMemoryString mutableArg(arg, strlen(arg));
        assert(mutableArg);
        bool parseRes = ParseFaultInjectionStr(mutableArg.Get(), faultMgrFnTable, faultMgrFnTableLen);
        if (!parseRes)
        {
            PrintArgError("%s: Invalid string specified for fault injection option: %s\n", progName, arg);
            return false;
        }
        break;
    }
    case kToolCommonOpt_FaultTestIterations:
        if ((!ParseInt(arg, TestIterations)) || (TestIterations == 0))
        {
            PrintArgError("%s: Invalid value specified for the number of iterations to execute: %s\n", progName, arg);
            return false;
        }
        break;
    case kToolCommonOpt_DebugResourceUsage:
        DebugResourceUsage = true;
        break;
    case kToolCommonOpt_PrintFaultCounters:
        PrintFaultCounters = true;
        break;
    case kToolCommonOpt_ExtraCleanupTime:
        if ((!ParseInt(arg, ExtraCleanupTimeMsec)) || (ExtraCleanupTimeMsec == 0))
        {
            PrintArgError("%s: Invalid value specified for the extra time to wait before checking for leaks: %s\n", progName, arg);
            return false;
        }
        break;
#endif // CHIP_CONFIG_TEST || CHIP_SYSTEM_CONFIG_TEST || INET_CONFIG_TEST
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}
#endif // defined(CHIP_WITH_NLFAULTINJECTION) && CHIP_WITH_NLFAULTINJECTION
