/*
 *
 *    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
 *       A tool for exercising the Weave Binding interface.
 *
 */

#define __STDC_FORMAT_MACROS
#define __STDC_LIMIT_MACROS

#include <inttypes.h>
#include <limits.h>
#include <signal.h>

#include "ToolCommon.h"
#include <Weave/WeaveVersion.h>
#include <Weave/Core/WeaveBinding.h>
#include <Weave/Support/WeaveFaultInjection.h>
#include <Weave/Profiles/common/CommonProfile.h>

#define VerifyOrQuit(TST) \
do { \
    if (!(TST)) \
    { \
        fprintf(stderr, "CHECK FAILED: %s at %s:%d\n", #TST, __FUNCTION__, __LINE__); \
        exit(EXIT_FAILURE); \
    } \
} while (0)

#define TOOL_NAME "TestBinding"

enum TestMode
{
    kTestMode_Sequential,
    kTestMode_Simultaneous,
};

class BindingTestDriver
{
public:
    nl::Weave::Binding *binding;
    ExchangeContext *ec;
    uint32_t echosSent;
    bool defaultCheckDelivered;

    BindingTestDriver()
    {
        binding = NULL;
        ec = NULL;
        echosSent = 0;
        defaultCheckDelivered = false;
    }

    void Run();

private:
    void PrepareBinding();
    void SendEcho();
    void Complete();
    void Failed(WEAVE_ERROR err, const char *desc);

    static void DoOnDemandPrepare(System::Layer* aLayer, void* aAppState, System::Error aError);
    static void BindingEventCallback(void *apAppState, Binding::EventType aEvent, const Binding::InEventParam& aInParam, Binding::OutEventParam& aOutParam);
    static void SendDelayComplete(System::Layer* aLayer, void* aAppState, System::Error aError);
    static void OnEchoResponseReceived(ExchangeContext *ec, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, uint32_t profileId,
            uint8_t msgType, PacketBuffer *payload);
    static void OnResponseTimeout(ExchangeContext *ec);
    static void OnMessageSendError(ExchangeContext *ec, WEAVE_ERROR err, void *msgCtxt);
};

static bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg);
static bool HandleNonOptionArgs(const char *progName, int argc, char *argv[]);
static bool ParseDestAddress(const char *destAddr);
static void StartTest();

static bool gUseTCP = true;
static bool gUseUDP = false;
static bool gUseWRMP = false;
static uint64_t gDestNodeId = kNodeIdNotSpecified;
static IPAddress gDestIPAddr = IPAddress::Any;
static uint16_t gDestPort = WEAVE_PORT;
static InterfaceId gDestIntf = INET_NULL_INTERFACEID;
static uint32_t gTestCount = 1;
static uint32_t gEchoCount = 5;
static uint32_t gEchoSendDelay = 100; // in ms
static uint32_t gEchoResponseTimeout = 5000; // in ms
static bool gOnDemandPrepare = false;

static TestMode gSelectedTestMode = kTestMode_Sequential;
static uint32_t gTestDriversStarted = 0;
static uint32_t gTestDriversActive = 0;

enum
{
    kToolOpt_EchoCount               = 1000,
    kToolOpt_EchoResponseTimeout     = 1001,
    kToolOpt_OnDemandPrepare         = 1002,
};

static OptionDef gToolOptionDefs[] =
{
    { "test-mode",              kArgumentRequired, 'm'                          },
    { "test-count",             kArgumentRequired, 'C'                          },
    { "echo-count",             kArgumentRequired, kToolOpt_EchoCount           },
    { "resp-timeout",           kArgumentRequired, kToolOpt_EchoResponseTimeout },
    { "on-demand-prepare",      kNoArgument,       kToolOpt_OnDemandPrepare     },
    { "dest-addr",              kArgumentRequired, 'D'                          },
    { "tcp",                    kNoArgument,       't'                          },
    { "udp",                    kNoArgument,       'u'                          },
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    { "wrmp",                   kNoArgument,       'w'                          },
#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    { NULL }
};

static const char *const gToolOptionHelp =
    "  -m, --test-mode <mode>\n"
    "       Binding test mode.  The following modes are available:\n"
    "\n"
    "         sequential   -- Perform test sequences sequentially.\n"
    "         simultaneous -- Perform test sequences simultaneously.\n"
    "\n"
    "  -C, --test-count <int>\n"
    "       The number of test sequences to be executed. Defaults to 1.\n"
    "\n"
    "  --echo-count <int>\n"
    "       The number of Echo requests to be sent. Defaults to 5.\n"
    "\n"
    "  --resp-timeout <ms>\n"
    "       The amount of time to wait for an echo response from the peer. Defaults\n"
    "       to 5 seconds.\n"
    "\n"
    "  --on-demand-prepare\n"
    "       Test the \"on demand\" prepare pattern using the Binding::RequestPrepare() method.\n"
    "\n"
    "  -D, --dest-addr <ip-addr>[:<port>][%<interface>]\n"
    "       Send echo requests to the peer at the specific address, port and interface.\n"
    "\n"
    "       NOTE: When specifying a port with an IPv6 address, the IPv6 address\n"
    "       must be enclosed in brackets, e.g. [fd00:0:1:1::1]:11095.\n"
    "\n"
    "  -t, --tcp\n"
    "       Use TCP to interact with the peer. This is the default.\n"
    "\n"
    "  -u, --udp\n"
    "       Use UDP to interact with the peer.\n"
    "\n"
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    "  -w, --wrmp\n"
    "       Use UDP with Weave Reliable Messaging to interact with the peer.\n"
    "\n"
#endif
    ;

static OptionSet gToolOptions =
{
    HandleOption,
    gToolOptionDefs,
    "GENERAL OPTIONS",
    gToolOptionHelp
};

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options...>] <dest-node-id>[@<ip-addr>[:<port>][%<interface>]]\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT,
    "Test the Weave Binding interface.\n"
    "\n"
    "This tool performs one or more test sequences involving the use of a Weave Binding object.\n"
    "Each test sequence performs the following steps:\n"
    "\n"
    "    - Create and prepare a Binding object\n"
    "    - Use the binding to send and receive a sequence of Weave Echo request/responses\n"
    "    - Close the binding\n"
    "\n"
    "Command line options can be used to configure the behavior of the test sequence and/or\n"
    "introduce failures.  At each step, various checks are made to ensure correct operation\n"
    "of the Binding object.\n"
    "\n"
    "The " TOOL_NAME " tool is typically used in conjunction with the weave-ping tool acting\n"
    "as a responder.\n"
    "\n"
);

static OptionSet *gToolOptionSets[] =
{
    &gToolOptions,
    &gNetworkOptions,
    &gWeaveNodeOptions,
    &gWRMPOptions,
    &gWeaveSecurityMode,
    &gCASEOptions,
    &gTAKEOptions,
    &gGroupKeyEncOptions,
    &gDeviceDescOptions,
    &gServiceDirClientOptions,
    &gFaultInjectionOptions,
    &gHelpOptions,
    NULL
};

int main(int argc, char *argv[])
{
#if WEAVE_CONFIG_TEST
    nl::Weave::System::Stats::Snapshot before;
    nl::Weave::System::Stats::Snapshot after;
#endif

    InitToolCommon();

#if WEAVE_CONFIG_TEST
    SetupFaultInjectionContext(argc, argv);
    SetSignalHandler(DoneOnHandleSIGUSR1);
#endif

    if (argc == 1)
    {
        gHelpOptions.PrintBriefUsage(stderr);
        exit(EXIT_FAILURE);
    }

    if (!ParseArgsFromEnvVar(TOOL_NAME, TOOL_OPTIONS_ENV_VAR_NAME, gToolOptionSets, NULL, true) ||
        !ParseArgs(TOOL_NAME, argc, argv, gToolOptionSets, HandleNonOptionArgs))
    {
        exit(EXIT_FAILURE);
    }

    // TODO (arg clean up): generalize code that infers node ids from local address
    if (gNetworkOptions.LocalIPv6Addr != IPAddress::Any)
    {
        if (!gNetworkOptions.LocalIPv6Addr.IsIPv6ULA())
        {
            printf("ERROR: Local address must be an IPv6 ULA\n");
            exit(EXIT_FAILURE);
        }

        gWeaveNodeOptions.FabricId = gNetworkOptions.LocalIPv6Addr.GlobalId();
        gWeaveNodeOptions.LocalNodeId = IPv6InterfaceIdToWeaveNodeId(gNetworkOptions.LocalIPv6Addr.InterfaceId());
        gWeaveNodeOptions.SubnetId = gNetworkOptions.LocalIPv6Addr.Subnet();
    }

    switch (gWeaveSecurityMode.SecurityMode)
    {
    case WeaveSecurityMode::kNone:
    case WeaveSecurityMode::kCASE:
    case WeaveSecurityMode::kCASEShared:
    case WeaveSecurityMode::kGroupEnc:
        break;
    default:
        printf("ERROR: Unsupported security mode specified\n");
        exit(EXIT_FAILURE);
    }

    InitSystemLayer();
    InitNetwork();
    InitWeaveStack(false, true);

#if WEAVE_CONFIG_TEST
    nl::Weave::Stats::UpdateSnapshot(before);

    for (uint32_t iter = 0; iter < gFaultInjectionOptions.TestIterations; iter++)
    {
        printf("FI Iteration %u\n", iter);
#endif // WEAVE_CONFIG_TEST

        StartTest();
        ServiceNetworkUntil(&Done, NULL);

#if WEAVE_CONFIG_TEST
        if (gSigusr1Received)
        {
            printf("Sigusr1Received\n");
            break;
        }
    }

    ProcessStats(before, after, true, NULL);
    PrintFaultInjectionCounters();
#endif // WEAVE_CONFIG_TEST

    ShutdownWeaveStack();
    ShutdownNetwork();
    ShutdownSystemLayer();

    return EXIT_SUCCESS;
}

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 'm':
        if (strcasecmp(arg, "sequential") == 0)
        {
            gSelectedTestMode = kTestMode_Sequential;
        }
        else if (strcasecmp(arg, "simultaneous") == 0)
        {
            gSelectedTestMode = kTestMode_Simultaneous;
        }
        else
        {
            PrintArgError("%s: Invalid value specified for test mode: %s\n", progName, arg);
            return false;
        }
        break;
    case 'C':
        if (!ParseInt(arg, gTestCount))
        {
            PrintArgError("%s: Invalid value specified for test count: %s\n", progName, arg);
            return false;
        }
        break;
    case kToolOpt_EchoCount:
        if (!ParseInt(arg, gEchoCount))
        {
            PrintArgError("%s: Invalid value specified for echo count: %s\n", progName, arg);
            return false;
        }
        break;
    case kToolOpt_EchoResponseTimeout:
        if (!ParseInt(arg, gEchoResponseTimeout))
        {
            PrintArgError("%s: Invalid value specified for response timeout: %s\n", progName, arg);
            return false;
        }
        break;
    case kToolOpt_OnDemandPrepare:
        gOnDemandPrepare = true;
        break;
    case 't':
        gUseTCP = true;
        gUseUDP = false;
        gUseWRMP = false;
        break;
    case 'u':
        gUseTCP = false;
        gUseUDP = true;
        gUseWRMP = false;
        break;
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    case 'w':
        gUseTCP = false;
        gUseUDP = false;
        gUseWRMP = true;
        break;
#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
    case 'D':
        if (!ParseDestAddress(arg))
        {
            PrintArgError("%s: Invalid value specified for destination address: %s\n", progName, arg);
            return false;
        }
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

bool HandleNonOptionArgs(const char *progName, int argc, char *argv[])
{
    if (argc == 0)
    {
        PrintArgError("%s: Please specify a destination node id\n", progName);
        return false;
    }

    if (argc > 1)
    {
        PrintArgError("%s: Unexpected argument: %s\n", progName, argv[1]);
        return false;
    }

    const char *nodeId = argv[0];
    char *destAddr = (char *)strchr(nodeId, '@');
    if (destAddr != NULL)
    {
        *destAddr = 0;
        destAddr++;
    }

    if (!ParseNodeId(nodeId, gDestNodeId))
    {
        PrintArgError("%s: Invalid value specified for destination node-id: %s\n", progName, nodeId);
        return false;
    }

    if (destAddr != NULL && !ParseDestAddress(destAddr))
    {
        PrintArgError("%s: Invalid value specified for destination address: %s\n", progName, destAddr);
        return false;
    }

    return true;
}

bool ParseDestAddress(const char *destAddr)
{
    const char *host;
    uint16_t hostLen;

    if (ParseHostAndPort(destAddr, strlen(destAddr), host, hostLen, gDestPort) != WEAVE_NO_ERROR)
    {
        return false;
    }

    char *hostCopy = strndup(host, hostLen);
    bool isValidAddr = IPAddress::FromString(hostCopy, gDestIPAddr);
    free(hostCopy);

    return isValidAddr;
}

void StartTest()
{
    BindingTestDriver *bindingProc;

    gTestDriversStarted = 0;
    gTestDriversActive = 0;

    switch (gSelectedTestMode)
    {
    case kTestMode_Sequential:
        bindingProc = new BindingTestDriver();
        bindingProc->Run();
        break;
    case kTestMode_Simultaneous:
        for (uint32_t i = 0; i < gTestCount; i++)
        {
            bindingProc = new BindingTestDriver();
            bindingProc->Run();
        }
        break;
    }
}

void BindingTestDriver::Run()
{
    gTestDriversStarted++;
    gTestDriversActive++;

    // Construct a new binding object.
    binding = ExchangeMgr.NewBinding(BindingEventCallback, this);
    if (binding == NULL)
    {
        Failed(WEAVE_ERROR_NO_MEMORY, "WeaveExchangeManager::NewBinding() failed");
        return;
    }

    VerifyOrQuit(binding->GetState() == Binding::kState_NotConfigured);
    VerifyOrQuit(!binding->IsReady());
    VerifyOrQuit(!binding->IsPreparing());
    VerifyOrQuit(binding->CanBePrepared());

    VerifyOrQuit(defaultCheckDelivered);

    if (gOnDemandPrepare)
    {
        SystemLayer.ScheduleWork(DoOnDemandPrepare, this);
    }
    else
    {
        PrepareBinding();
    }
}

void BindingTestDriver::PrepareBinding()
{
    WEAVE_ERROR err;

    VerifyOrQuit(binding->CanBePrepared());

    // Begin configuring the binding.
    Binding::Configuration bindingConf = binding->BeginConfiguration();

    VerifyOrQuit(binding->GetState() == Binding::kState_Configuring);

    // Configure the target node id
    bindingConf.Target_NodeId(gDestNodeId);

    // Configure the target address.
    if (gDestIPAddr != IPAddress::Any)
    {
        bindingConf.TargetAddress_IP(gDestIPAddr, gDestPort, gDestIntf);
    }

    // Configure the transport.
    if (gUseTCP)
    {
        bindingConf.Transport_TCP();
    }
    else if (gUseUDP)
    {
        bindingConf.Transport_UDP();
    }
    else if (gUseWRMP)
    {
        bindingConf.Transport_UDP_WRM();
        bindingConf.Transport_DefaultWRMPConfig(gWRMPOptions.GetWRMPConfig());
    }

    // Configure the security mode.
    switch (gWeaveSecurityMode.SecurityMode)
    {
    case WeaveSecurityMode::kNone:
    default:
        bindingConf.Security_None();
        break;
    case WeaveSecurityMode::kCASE:
        bindingConf.Security_CASESession();
        break;
    case WeaveSecurityMode::kCASEShared:
        bindingConf.Security_SharedCASESession();
        break;
    case WeaveSecurityMode::kGroupEnc:
        bindingConf.Security_Key(gGroupKeyEncOptions.GetEncKeyId());
        break;
    }

    bindingConf.Exchange_ResponseTimeoutMsec(gEchoResponseTimeout);

    // Prepare the binding.
    err = bindingConf.PrepareBinding();
    if (err != WEAVE_NO_ERROR)
    {
        Failed(err, "Binding::Configuration::PrepareBinding() failed");
        return;
    }

    VerifyOrQuit(binding->GetState() != Binding::kState_Configuring);
}

void BindingTestDriver::DoOnDemandPrepare(System::Layer* aLayer, void* aAppState, System::Error aError)
{
    WEAVE_ERROR err;
    BindingTestDriver *_this = (BindingTestDriver *)aAppState;

    err = _this->binding->RequestPrepare();
    if (err != WEAVE_NO_ERROR)
    {
        _this->Failed(err, "Binding::RequestPrepare() failed");
    }
}

void BindingTestDriver::BindingEventCallback(void *apAppState, Binding::EventType aEvent, const Binding::InEventParam& aInParam, Binding::OutEventParam& aOutParam)
{
    BindingTestDriver *_this = (BindingTestDriver *)apAppState;
    Binding *binding = aInParam.Source;

    switch (aEvent)
    {
    case Binding::kEvent_BindingReady:
        VerifyOrQuit(binding->GetState() == Binding::kState_Ready);
        VerifyOrQuit(binding->IsReady());
        VerifyOrQuit(!binding->IsPreparing());
        VerifyOrQuit(!binding->CanBePrepared());
        _this->SendEcho();
        break;
    case Binding::kEvent_PrepareFailed:
        VerifyOrQuit(binding->GetState() == Binding::kState_Failed);
        VerifyOrQuit(!binding->IsReady());
        VerifyOrQuit(!binding->IsPreparing());
        VerifyOrQuit(binding->CanBePrepared());
        _this->Failed(aInParam.PrepareFailed.Reason, "Prepare failed");
        break;
    case Binding::kEvent_BindingFailed:
        VerifyOrQuit(binding->GetState() == Binding::kState_Failed);
        VerifyOrQuit(!binding->IsReady());
        VerifyOrQuit(!binding->IsPreparing());
        VerifyOrQuit(binding->CanBePrepared());
        _this->Failed(aInParam.PrepareFailed.Reason, "Binding failed");
        break;
    case Binding::kEvent_PrepareRequested:
        VerifyOrQuit(binding->GetState() == Binding::kState_NotConfigured);
        VerifyOrQuit(!binding->IsReady());
        VerifyOrQuit(!binding->IsPreparing());
        VerifyOrQuit(binding->CanBePrepared());
        _this->PrepareBinding();
        break;
    case Binding::kEvent_DefaultCheck:
        _this->defaultCheckDelivered = true;
        binding->DefaultEventHandler(apAppState, aEvent, aInParam, aOutParam);
        break;
    default:
        fprintf(stderr, "UNEXPECTED BINDING EVENT: %d\n", (int)aEvent);
        exit(EXIT_FAILURE);
    }
}

void BindingTestDriver::SendEcho()
{
    WEAVE_ERROR err;
    PacketBuffer *msgBuf = NULL;

    err = binding->NewExchangeContext(ec);
    if (err != WEAVE_NO_ERROR)
    {
        Failed(err, "Binding::NewExchangeContext() failed");
        return;
    }

    ec->AppState = this;

    ec->OnMessageReceived = OnEchoResponseReceived;
    ec->OnResponseTimeout = OnResponseTimeout;
    ec->OnSendError = OnMessageSendError;

    // Allocate a buffer for the echo request message
    msgBuf = PacketBuffer::NewWithAvailableSize(0);
    if (msgBuf == NULL)
    {
        Failed(WEAVE_ERROR_NO_MEMORY, "PacketBuffer::NewWithAvailableSize() failed");
        return;
    }

    // Send the null message
    err = ec->SendMessage(nl::Weave::Profiles::kWeaveProfile_Echo,
                          nl::Weave::Profiles::kEchoMessageType_EchoRequest,
                          msgBuf,
                          ExchangeContext::kSendFlag_ExpectResponse);
    if (err != WEAVE_NO_ERROR)
    {
        Failed(err, "ExchangeContext::SendMessage() failed");
        return;
    }
}

void BindingTestDriver::SendDelayComplete(System::Layer* aLayer, void* aAppState, System::Error aError)
{
    BindingTestDriver *_this = (BindingTestDriver *)aAppState;
    _this->SendEcho();
}

void BindingTestDriver::OnEchoResponseReceived(ExchangeContext *ec, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, uint32_t profileId,
        uint8_t msgType, PacketBuffer *payload)
{
    BindingTestDriver *_this = (BindingTestDriver *)ec->AppState;

    PacketBuffer::Free(payload);

    ec->Close();
    _this->ec = NULL;

    _this->echosSent++;

    VerifyOrQuit(_this->binding->IsAuthenticMessageFromPeer(msgInfo));

    if (_this->echosSent < gEchoCount)
    {
        if (gEchoSendDelay == 0)
        {
            _this->SendEcho();
        }
        else
        {
            SystemLayer.StartTimer(gEchoSendDelay, SendDelayComplete, _this);
        }
    }
    else
    {
        _this->Complete();
    }
}

void BindingTestDriver::Complete()
{
    gTestDriversActive--;

    binding->Close();
    binding = NULL;

    switch (gSelectedTestMode)
    {
    case kTestMode_Sequential:
        if (gTestDriversStarted < gTestCount)
        {
            BindingTestDriver *testDriver = new BindingTestDriver();
            testDriver->Run();
        }
        else
        {
            Done = true;
        }
        break;
    case kTestMode_Simultaneous:
        if (gTestDriversActive == 0)
        {
            Done = true;
        }
        break;
    }

    delete this;
}

void BindingTestDriver::Failed(WEAVE_ERROR err, const char *reason)
{
    gTestDriversActive--;

    if (binding != NULL)
    {
        binding->Close();
        binding = NULL;
    }

    if (ec != NULL)
    {
        ec->Abort();
        ec = NULL;
    }

    fprintf(stderr, "Test Failed: %s: %s\n", reason, ErrorStr(err));
    exit(EXIT_FAILURE);
}

void BindingTestDriver::OnResponseTimeout(ExchangeContext *ec)
{
    BindingTestDriver *_this = (BindingTestDriver *)ec->AppState;
    _this->Failed(WEAVE_ERROR_TIMEOUT, "Failed to receive response for Echo request");
}

void BindingTestDriver::OnMessageSendError(ExchangeContext *ec, WEAVE_ERROR err, void *msgCtxt)
{
    BindingTestDriver *_this = (BindingTestDriver *)ec->AppState;
    _this->Failed(err, "Failed to receive ACK for Echo request");
}
