/*
 *
 *    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 aims to test the service directory profile.
 *
 */

#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <limits.h>

#include "ToolCommon.h"
#include <Weave/WeaveVersion.h>
#include <Weave/Profiles/service-directory/ServiceDirectory.h>
#include "MockSDServer.h"

#define TOOL_NAME "weave-service-dir"

static void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);
static void HandleServiceMgrStatus(void *appState, WEAVE_ERROR anError, StatusReport *aReport);
static void HandleTestTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);

enum
{
    kRole_ServiceDirServer = 0,
    kRole_ServiceDirClient,
};

uint8_t Role = kRole_ServiceDirServer;
ServiceDirectory::WeaveServiceManager ServiceMgr;
uint8_t ServiceDirCache[300];
const char *DirectoryServer = NULL;
WeaveAuthMode AuthMode = kWeaveAuthMode_Unauthenticated;
MockServiceDirServer MockSDServer;
static bool sLastIterationFailed = false;
static bool sTimerRunning = false;

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options...>]\n"
    "       " TOOL_NAME " [<options...>] --service-dir-server <host>[:<port>]\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT
);

static OptionSet *gToolOptionSets[] =
{
    &gNetworkOptions,
    &gWeaveNodeOptions,
    &gServiceDirClientOptions,
    &gFaultInjectionOptions,
    &gHelpOptions,
    NULL
};

static void HandleTestTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError)
{
    printf("test timeout\n");

    sTimerRunning = false;
    Done = true;
    ServiceMgr.cancel(kServiceEndpoint_SoftwareUpdate, static_cast<void *>(&ServiceMgr));
}

static void ExpireTimer(int32_t argument)
{
    SystemLayer.StartTimer(0, HandleTestTimeout, NULL);
}

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

    if (Role == kRole_ServiceDirClient && sTimerRunning)
    {
        retval = 1;
    }

    return retval;
}

int main(int argc, char *argv[])
{
    WEAVE_ERROR err;
    nl::Weave::System::Stats::Snapshot before;
    nl::Weave::System::Stats::Snapshot after;
    const bool printStats = true;

    InitToolCommon();

    SetupFaultInjectionContext(argc, argv, GetNumEventsAvailable, ExpireTimer);
    SetSignalHandler(DoneOnHandleSIGUSR1);

    gServiceDirClientOptions.ServerHost = NULL;

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

    Role = (gServiceDirClientOptions.ServerHost != NULL) ? kRole_ServiceDirClient : kRole_ServiceDirServer;

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

    PrintNodeConfig();

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

    if (Role == kRole_ServiceDirServer)
    {
        // Initialize the mock service directory server.
        err = MockSDServer.Init(&ExchangeMgr);
        FAIL_ERROR(err, "MockSDServer.Init failed");
    }
    else
    {
        err = ServiceMgr.init(&ExchangeMgr, ServiceDirCache, sizeof(ServiceDirCache),
            GetRootServiceDirectoryEntry, AuthMode, NULL, NULL, OverrideServiceConnectArguments);
        if (err != WEAVE_NO_ERROR)
        {
            printf("ServiceMgr.init() failed with error: %s\n", ErrorStr(err));
            exit(EXIT_FAILURE);
        }

    }

    for (uint32_t iteration = 1; iteration <= gFaultInjectionOptions.TestIterations; iteration++)
    {

        if (Role == kRole_ServiceDirClient)
        {
            sLastIterationFailed = false;

            printf("Iteration %u\n", iteration);

            // Ask for a connection to SoftwareUpdate; the MockSDServer responds to both

            SystemLayer.StartTimer(30000, HandleTestTimeout, NULL);
            sTimerRunning = true;

            err = ServiceMgr.connect(kServiceEndpoint_SoftwareUpdate,
                    AuthMode,
                    static_cast<void *>(&ServiceMgr), // you have to put something here, or the status callback is not invoked
                    HandleServiceMgrStatus,
                    HandleConnectionComplete);
            if (err != WEAVE_NO_ERROR)
            {
                printf("WeaveServiceManager.Connect(): failed: %s\n", ErrorStr(err));
                Done = true;
                sLastIterationFailed = true;
            }

        }

        ServiceNetworkUntil(&Done);

        SystemLayer.CancelTimer(HandleTestTimeout, NULL);
        sTimerRunning = false;

        if (sLastIterationFailed)
        {
            // Sleep a couple of seconds; if a new attempt is made too soon, the service process can
            // reject the connection (e.g. if it is restarting after a crash)
            uint32_t waitTimeMs = 2000;

            ServiceNetworkUntil(NULL, &waitTimeMs);
        }

        Done = false;
    }

    ServiceMgr.relocate(WEAVE_NO_ERROR);
    ServiceMgr.reset(WEAVE_NO_ERROR);
    ServiceMgr.unresolve(WEAVE_NO_ERROR);
    ServiceMgr.cancel(kServiceEndpoint_SoftwareUpdate, NULL);

    if (Role == kRole_ServiceDirServer)
    {
        err = MockSDServer.TearDown();
        FAIL_ERROR(err, "MockSDServer.TearDown failed");
    }

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

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

    return EXIT_SUCCESS;
}

void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr)
{
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    if (conErr != WEAVE_NO_ERROR)
    {
        printf("Connection failed to node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);
        sLastIterationFailed = true;
    }
    else
        printf("Connection established to node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);

    // stop the test
    con->Close();
    Done = true;
}

void HandleServiceMgrStatus(void* anAppState, WEAVE_ERROR anError, StatusReport *aReport)
{
    if (aReport)
        printf("service directory status report [%" PRIx32 ", %" PRIx32 "] %s\n", aReport->mProfileId, aReport->mStatusCode,
                nl::StatusReportStr(aReport->mProfileId, aReport->mStatusCode));
    else
    {
        printf("service directory error %" PRIx32 " %s\n", static_cast<uint32_t>(anError), nl::ErrorStr(anError));
        if (anError == WEAVE_ERROR_INVALID_SERVICE_EP)
        {
            ServiceMgr.clearCache();
        }
        sLastIterationFailed = true;
    }

    Done = true;
}
