/*
 *
 *    Copyright (c) 2016-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
 *      This file implements test app for the Weave Data Management(WDM) Next Profile.
 *
 *
 */

#define __STDC_FORMAT_MACROS

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

// Note that the choice of namespace alias must be made up front for each and every compile unit
// This is because many include paths could set the default alias to unintended target.
#include <Weave/Profiles/bulk-data-transfer/Development/BDXManagedNamespace.hpp>
#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>

#include "ToolCommon.h"
#include <Weave/Core/WeaveTLV.h>
#include <Weave/Core/WeaveCore.h>
#include <Weave/WeaveVersion.h>
#include "MockLoggingManager.h"
#include "MockWdmSubscriptionInitiator.h"
#include <Weave/Support/CodeUtils.h>
#include <Weave/Profiles/WeaveProfiles.h>
#include <Weave/Profiles/common/CommonProfile.h>
#include <Weave/Profiles/time/WeaveTime.h>
#include <SystemLayer/SystemTimer.h>
#include <time.h>
#include "MockLoggingManager.h"

#include "MockWdmSubscriptionInitiator.h"
#include "MockWdmSubscriptionResponder.h"
#include "MockWdmViewClient.h"
#include "MockWdmViewServer.h"
#include "WdmNextPerfUtility.h"
#include "TestWdmSubscriptionlessNotification.h"
#include "MockWdmNodeOptions.h"

using nl::Inet::IPAddress;
using namespace nl::Weave;
using namespace nl::Weave::TLV;
using namespace nl::Weave::Profiles;
using nl::Weave::WeaveExchangeManager;

#define TOOL_NAME "TestWdmNext"

static void HandleWdmCompleteTest();
static void HandleError();


// events
EventGenerator * gEventGenerator = NULL;
uint32_t TestWdmSublessNotifyDelayMsec = 6000;

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options>]\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT
);

static OptionSet *gToolOptionSets[] =
{
    &gTestWdmNextOptions,
    &gMockWdmNodeOptions,
    &gNetworkOptions,
    &gWeaveNodeOptions,
    &gWeaveSecurityMode,
    &gFaultInjectionOptions,
    &gHelpOptions,
    &gCASEOptions,
    &gGroupKeyEncOptions,
    NULL
};

static int32_t GetNumFaultInjectionEventsAvailable(void)
{
    int32_t retval = 0;

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    MockWdmSubscriptionInitiator *initiator = MockWdmSubscriptionInitiator::GetInstance();

    retval = initiator->GetNumFaultInjectionEventsAvailable();
#endif

    return retval;

}
static void ExpireTimer(int32_t argument)
{
    ExchangeMgr.ExpireExchangeTimers();
}


int main(int argc, char *argv[])
{
    WEAVE_ERROR err;
    WdmNextPerfUtility &TimeRef = *WdmNextPerfUtility::Instance();
    struct timeval sleepTime;
    time_t begin, end;
    double seconds = 0;
    sleepTime.tv_sec = 0;
    sleepTime.tv_usec = 100000;
    nl::Weave::System::Stats::Snapshot before;
    nl::Weave::System::Stats::Snapshot after;
    const bool printStats = true;

    gMockWdmNodeOptions.mWdmUpdateMaxNumberOfTraits = MockWdmSubscriptionInitiator::GetNumUpdatableTraits();

    InitToolCommon();

    SetupFaultInjectionContext(argc, argv,
            GetNumFaultInjectionEventsAvailable, ExpireTimer);

    SetSignalHandler(DoneOnHandleSIGUSR1);

    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) ||
        !ResolveWeaveNetworkOptions(TOOL_NAME, gWeaveNodeOptions, gNetworkOptions))
    {
        exit(EXIT_FAILURE);
    }

    // This test program enables faults and stats prints always (no option taken from the CLI)
    gFaultInjectionOptions.DebugResourceUsage = true;
    gFaultInjectionOptions.PrintFaultCounters = true;

    InitSystemLayer();

    InitNetwork();

    InitWeaveStack(true, true);

    InitializeEventLogging(&ExchangeMgr);

    switch (gMockWdmNodeOptions.mWdmRoleInTest)
    {
        case 0:
            break;

#if ENABLE_VIEW_TEST

        case kToolOpt_WdmSimpleViewClient:
                if (gMockWdmNodeOptions.mWdmPublisherNodeId != kAnyNodeId)
                {
                    err = MockWdmViewClient::GetInstance()->Init(&ExchangeMgr, gMockWdmNodeOptions.mTestCaseId);
                    FAIL_ERROR(err, "MockWdmViewClient.Init failed");
                    MockWdmViewClient::GetInstance()-> onCompleteTest = HandleWdmCompleteTest;
                }
                else
                {
                    err = WEAVE_ERROR_INVALID_ARGUMENT;
                    FAIL_ERROR(err, "Simple View Client requires node ID to some publisher");
                }

                break;
            case kToolOpt_WdmSimpleViewServer:
                err = MockWdmViewServer::GetInstance()->Init(&ExchangeMgr, gMockWdmNodeOptions.mTestCaseId);
                FAIL_ERROR(err, "MockWdmViewServer.Init failed");
                break;

#endif // ENABLE_VIEW_TEST

#if WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION
        case kToolOpt_WdmSimpleSublessNotifyClient:
                err = TestWdmSubscriptionlessNotificationReceiver::GetInstance()->Init(&ExchangeMgr);
                FAIL_ERROR(err, "TestWdmSubscriptionlessNotificationReceiver.Init failed");

                TestWdmSubscriptionlessNotificationReceiver::GetInstance()->OnTestComplete = HandleWdmCompleteTest;

                TestWdmSubscriptionlessNotificationReceiver::GetInstance()->OnError = HandleError;
            break;
        case kToolOpt_WdmSimpleSublessNotifyServer:
                time(&begin);

                while (seconds * 1000 < TestWdmSublessNotifyDelayMsec)
                {
                    ServiceNetwork(sleepTime);
                    time(&end);
                    seconds = difftime(end, begin);
                }
                printf("delay %d milliseconds\n", TestWdmSublessNotifyDelayMsec);
                seconds = 0;

                if (gMockWdmNodeOptions.mWdmSublessNotifyDestNodeId != kAnyNodeId)
                {
                    err = TestWdmSubscriptionlessNotificationSender::GetInstance()->Init(&ExchangeMgr,
                                                                                         gMockWdmNodeOptions.mWdmUseSubnetId,
                                                                                         gMockWdmNodeOptions.mWdmSublessNotifyDestNodeId);
                    FAIL_ERROR(err, "TestWdmSubscriptionlessNotificationSender.Init failed");
                }
            break;
#endif // WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION
        case kToolOpt_WdmInitMutualSubscription:
        case kToolOpt_WdmSubscriptionClient:

            if (gMockWdmNodeOptions.mWdmPublisherNodeId != kAnyNodeId)
            {
                err = MockWdmSubscriptionInitiator::GetInstance()->Init(&ExchangeMgr,
                                                                        gGroupKeyEncOptions.GetEncKeyId(),
                                                                        gWeaveSecurityMode.SecurityMode,
                                                                        gMockWdmNodeOptions);
                FAIL_ERROR(err, "MockWdmSubscriptionInitiator.Init failed");
                MockWdmSubscriptionInitiator::GetInstance()->onCompleteTest = HandleWdmCompleteTest;
                MockWdmSubscriptionInitiator::GetInstance()->onError = HandleError;

            }
            else
            {
                err = WEAVE_ERROR_INVALID_ARGUMENT;
                FAIL_ERROR(err, "MockWdmSubscriptionInitiator requires node ID to some publisher");
            }

            break;
        case kToolOpt_WdmRespMutualSubscription:
        case kToolOpt_WdmSubscriptionPublisher:
            if (gMockWdmNodeOptions.mEnableRetry)
            {
                err = WEAVE_ERROR_INVALID_ARGUMENT;
                FAIL_ERROR(err, "MockWdmSubcriptionResponder is incompatible with --enable-retry");
            }

            err = MockWdmSubscriptionResponder::GetInstance()->Init(&ExchangeMgr,
                                                                    gMockWdmNodeOptions);
            FAIL_ERROR(err, "MockWdmSubscriptionResponder.Init failed");
            MockWdmSubscriptionResponder::GetInstance()->onCompleteTest = HandleWdmCompleteTest;
            MockWdmSubscriptionResponder::GetInstance()->onError = HandleError;
            if (gTestWdmNextOptions.mClearDataSinkState)
            {
                MockWdmSubscriptionResponder::GetInstance()->ClearDataSinkState();
            }
            break;
        default:
            err = WEAVE_ERROR_INVALID_ARGUMENT;
            FAIL_ERROR(err, "WdmRoleInTest is invalid");
    };

    nl::Weave::Stats::UpdateSnapshot(before);

    for (uint32_t iteration = 1; iteration <= gTestWdmNextOptions.mTestIterations; iteration++)
    {
        Done = false;

#ifdef ENABLE_WDMPERFDATA

        TimeRef();

#endif //ENABLE_WDMPERFDATA

        switch (gMockWdmNodeOptions.mWdmRoleInTest)
        {
        case 0:
            break;

#if ENABLE_VIEW_TEST

        case kToolOpt_WdmSimpleViewClient:
            if (gTestWdmNextOptions.mClearDataSinkState)
            {
                MockWdmViewClient::GetInstance()->ClearDataSinkState();
            }

            err = MockWdmViewClient::GetInstance()->StartTesting(WdmPublisherNodeId, WdmUseSubnetId);
            FAIL_ERROR(err, "MockWdmViewClient.StartTesting failed");
            break;

#endif

#if WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION
        case kToolOpt_WdmSimpleSublessNotifyClient:
            break;
        case kToolOpt_WdmSimpleSublessNotifyServer:
                if (gMockWdmNodeOptions.mWdmSublessNotifyDestNodeId != kAnyNodeId)
                {
                    err = TestWdmSubscriptionlessNotificationSender::GetInstance()->SendSubscriptionlessNotify();
                    Done = true;
                    FAIL_ERROR(err, "TestWdmSubscriptionlessNotificationSender.SendSubscriptionlessNotify failed");
                }
            break;
#endif // WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION
        case kToolOpt_WdmInitMutualSubscription:
        case kToolOpt_WdmSubscriptionClient:
            if (gTestWdmNextOptions.mClearDataSinkState)
            {
                MockWdmSubscriptionInitiator::GetInstance()->ClearDataSinkState();
            }
            err = MockWdmSubscriptionInitiator::GetInstance()->StartTesting(gMockWdmNodeOptions.mWdmPublisherNodeId, gMockWdmNodeOptions.mWdmUseSubnetId);
            if (err != WEAVE_NO_ERROR)
            {
                printf("\nMockWdmSubscriptionInitiator.StartTesting failed: %s\n", ErrorStr(err));
                Done = true;
            }
            //FAIL_ERROR(err, "MockWdmSubscriptionInitiator.StartTesting failed");
            break;
        default:
            printf("TestWdmNext server is ready\n");
        };

        PrintNodeConfig();

        switch (gMockWdmNodeOptions.mEventGeneratorType)
        {
            case MockWdmNodeOptions::kGenerator_None:
                gEventGenerator = NULL;
                break;
            case MockWdmNodeOptions::kGenerator_TestDebug:
                gEventGenerator = GetTestDebugGenerator();
                break;
            case MockWdmNodeOptions::kGenerator_TestLiveness:
                gEventGenerator = GetTestLivenessGenerator();
                break;
            case MockWdmNodeOptions::kGenerator_TestSecurity:
                gEventGenerator = GetTestSecurityGenerator();
                break;
            case MockWdmNodeOptions::kGenerator_TestTelemetry:
                gEventGenerator = GetTestTelemetryGenerator();
                break;
            case MockWdmNodeOptions::kGenerator_TestTrait:
                gEventGenerator = GetTestTraitGenerator();
                break;
            case MockWdmNodeOptions::kGenerator_NumItems:
            default:
                gEventGenerator = NULL;
                break;
        }

        if (gEventGenerator != NULL)
        {
            printf("Starting Event Generator\n");
            MockEventGenerator::GetInstance()->Init(&ExchangeMgr, gEventGenerator, gMockWdmNodeOptions.mTimeBetweenEvents, true);
        }

        printf("Start service network loop\n");
        while (!Done)
        {
            ServiceNetwork(sleepTime);
        }
        printf("End service network loop\n");

        MockEventGenerator::GetInstance()->SetEventGeneratorStop();

        if (gEventGenerator != NULL)
        {
            while (!MockEventGenerator::GetInstance()->IsEventGeneratorStopped())
            {
                ServiceNetwork(sleepTime);
            }
        }

        switch (gMockWdmNodeOptions.mWdmRoleInTest)
        {
            case kToolOpt_WdmInitMutualSubscription:
            case kToolOpt_WdmSubscriptionClient:
                if (gTestWdmNextOptions.mClearDataSinkState)
                {
                    MockWdmSubscriptionInitiator::GetInstance()->Cleanup();
                }
                break;
            default:
                break;
        }


#ifdef ENABLE_WDMPERFDATA

        TimeRef();
        TimeRef.SetPerf();
        TimeRef.ReportPerf();

#endif //ENABLE_WDMPERFDATA

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

        time(&begin);
        if (gTestWdmNextOptions.mTestDelayBetweenIterationMsec != 0)
        {
            while (seconds * 1000 < gTestWdmNextOptions.mTestDelayBetweenIterationMsec)
            {
                ServiceNetwork(sleepTime);
                time(&end);
                seconds = difftime(end, begin);
            }
            printf("delay %d milliseconds\n", gTestWdmNextOptions.mTestDelayBetweenIterationMsec);
            seconds = 0;
        }
        else
        {
            printf("no delay\n");
        }

        printf("Current completed test iteration is %d\n", iteration);
    }

    MockWdmSubscriptionInitiator::GetInstance()->PrintVersionsLog();
    MockWdmSubscriptionInitiator::GetInstance()->Cleanup();

    MockWdmSubscriptionResponder::GetInstance()->PrintVersionsLog();


    if (gTestWdmNextOptions.mSavePerfData)
    {
        TimeRef.SaveToFile();
    }

    TimeRef.Remove();

    ProcessStats(before, after, printStats, NULL);
    PrintFaultInjectionCounters();

#if WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION
    if (gMockWdmNodeOptions.mWdmRoleInTest == kToolOpt_WdmSimpleSublessNotifyServer)
    {
        err = TestWdmSubscriptionlessNotificationSender::GetInstance()->Shutdown();
        FAIL_ERROR(err, "TestWdmSubscriptionlessNotificationSender.Shutdown failed");
    }
#endif // WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION
    ShutdownWeaveStack();
    ShutdownNetwork();
    ShutdownSystemLayer();

    return 0;
}

static void HandleWdmCompleteTest()
{
    if (gMockWdmNodeOptions.mEnableStopTest)
    {
        printf("HandleWdmCompleteTest: Done = true\n");
        Done = true;
    }
}

static void HandleError()
{
    printf("HandleError: Done = true\n");
    Done = true;
}
