/*
 *
 *    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;
#if defined(CHIP_WITH_NLFAULTINJECTION) && CHIP_WITH_NLFAULTINJECTION
FaultInjectionOptions gFaultInjectionOptions;
#endif // defined(CHIP_WITH_NLFAULTINJECTION) && CHIP_WITH_NLFAULTINJECTION

NetworkOptions::NetworkOptions()
{
    static OptionDef optionDefs[] = {
        { "local-addr", kArgumentRequired, 'a' },
        { "node-addr", kArgumentRequired, kToolCommonOpt_NodeAddr }, /* alias for local-addr */
#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
        { "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 // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
        {}
    };
    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 || CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
                 "  --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 || CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
        ;

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

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

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;
}

#if defined(CHIP_WITH_NLFAULTINJECTION) && CHIP_WITH_NLFAULTINJECTION
FaultInjectionOptions::FaultInjectionOptions()
{
    static OptionDef optionDefs[] = { { "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 },
                                      {} };
    OptionDefs                    = optionDefs;

    HelpGroupName = "FAULT INJECTION OPTIONS";

    OptionHelp = "  --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"
                 "";

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

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)
    {
    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;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

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