/*
 *
 *    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
 *      This file implements a process to effect a functional test for
 *      a client for the Weave Software Update (SWU) profile.
 *
 */

#define __STDC_FORMAT_MACROS
#define __STDC_LIMIT_MACROS

#include <inttypes.h>

#include "ToolCommon.h"
#include <Weave/Core/WeaveSecurityMgr.h>
#include <Weave/Profiles/security/WeaveSecurity.h>
#include "nlweaveswuclient.h"
#include "MockIAServer.h"

using nl::StatusReportStr;
using namespace nl::Weave::Profiles;
using namespace nl::Weave::Profiles::Security;

#define TOOL_NAME "weave-swu-client"

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 void HandleConnectionReceived(WeaveMessageLayer *msgLayer, WeaveConnection *con);
static void StartClientConnection();
static void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);
static void HandleConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr);

bool Listening = false;
bool UseTCP = true;
bool Debug = false;
const char *DestIPAddrStr = NULL;
uint16_t DestPort; // only used for UDP
SoftwareUpdateClient SWUClient;
MockImageAnnounceServer MIAServer;

//Globals used by SWU-client
bool WaitingForSWUResp = false;
static uint64_t DestNodeId = 1;
IPAddress DestIPAddr;
WeaveConnection *Con = NULL;

static OptionDef gToolOptionDefs[] =
{
    { "listen",     kNoArgument,       'L' },
    { "dest-addr",  kArgumentRequired, 'D' },
    { "debug",      kArgumentRequired, 'd' },
    { "tcp",        kNoArgument,       't' },
    { "udp",        kNoArgument,       'u' },
    { }
};

static const char *gToolOptionHelp =
    "  -D, --dest-addr <host>[:<port>]\n"
    "       Send an ImageQuery request to a specific address rather than one\n"
    "       derived from the destination node id.  <host> can be a hostname,\n"
    "       an IPv4 address or an IPv6 address.  If <port> is specified, ImageQuery\n"
    "       requests will be sent to the specified port.\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 send SWU Requests. This is the default.\n"
    "\n"
    "  -u, --udp\n"
    "       Use UDP to send SWU Requests.\n"
    "\n"
    "  -L, --listen\n"
    "       Listen and respond to ImageAnnounce notifications sent from another node.\n"
    "\n"
    "  -d, --debug\n"
    "       Enable debug messages.\n"
    "\n";

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

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options...>] <dest-node-id>[@<dest-host>[:<dest-port>][%%<interface>]]\n"
    "       " TOOL_NAME " [<options...>] --listen\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT
);

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

static void HandleImageAnnounce(ExchangeContext *ec)
{
    WEAVE_ERROR err;

    printf("0 SWU HandleImageAnnounce entering\n");

    if (Listening)
    {
        printf("1 SWU HandleImageAnnounce (while listening, Con: %p)\n", Con);

        if (Con != NULL)
        {
            printf("2 SWU HandleImageAnnounce Sending TCP ImageQuery request\n");
            err = SWUClient.SendImageQueryRequest(Con);
        }
        else
        {
            char buffer[64];
            printf("3 SWU HandleImageAnnounce  (destIPAddr: %s (printed as a string))\n", DestIPAddr.ToString(buffer, strlen(buffer)));
            err = SWUClient.SendImageQueryRequest(DestNodeId, DestIPAddr);
        }
        if (err == WEAVE_NO_ERROR)
        {
            WaitingForSWUResp = true;
        }
        else
        {
            printf("4 SWUClient.SendRequest() failed: %X\n", err);
            Con->Close();
            Con = NULL;
        }
    }
    else
    {
        printf("5 SWU HandleImageAnnounce (while not listening)\n");
    }

    printf("6 SWU HandleImageAnnounce exiting\n");
}

int main(int argc, char *argv[])
{
    WEAVE_ERROR err;

    InitToolCommon();

    SetSIGUSR1Handler();

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

    InitSystemLayer();

    InitNetwork();

    InitWeaveStack(Listening || !UseTCP, true);

    // Arrange to get called for various activity in the message layer.
    MessageLayer.OnConnectionReceived = HandleConnectionReceived;
    MessageLayer.OnReceiveError = HandleMessageReceiveError;
    MessageLayer.OnAcceptError = HandleAcceptConnectionError;

    // Initialize the SWU-client application.
    err = SWUClient.Init(&ExchangeMgr);
    if (err != WEAVE_NO_ERROR)
    {
        printf("SoftwareUpdateClient::Init failed: %s\n", ErrorStr(err));
        exit(-1);
    }

    err = MIAServer.Init(&ExchangeMgr);
    if (err != WEAVE_NO_ERROR)
    {
        printf("MockImageAnnounceServer::Init failed: %s\n", ErrorStr(err));
        exit(-1);
    }
    MIAServer.OnImageAnnounceReceived = HandleImageAnnounce;

    PrintNodeConfig();

    if (!Listening)
    {
        if (DestNodeId == 0)
            printf("Sending SWU requests to node at %s\n", DestIPAddrStr);
        else if (DestIPAddrStr == NULL)
            printf("Sending SWU requests to node %" PRIX64 "\n", DestNodeId);
        else
            printf("Sending SWU requests to node %" PRIX64 " at %s\n", DestNodeId, DestIPAddrStr);

        //Set up connection and connect callbacks to handle success/failure cases
        StartClientConnection();
    }
    else
    {
        if (!UseTCP)
        {
            MIAServer.CreateExchangeCtx(DestNodeId, DestIPAddr);
        }
        printf("Listening for ImageAnnounce notifications...\n");
    }

    while (!Done)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec = 0;
        sleepTime.tv_usec = 100000;

        ServiceNetwork(sleepTime);
    }

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

    MIAServer.Shutdown();
    SWUClient.Shutdown();
    printf("Completed the SWU interactive protocol test!\n");
    ShutdownWeaveStack();
    ShutdownNetwork();
    ShutdownSystemLayer();

    return 0;
}

void StartClientConnection()
{
    printf("0 StartClientConnection entering (Con: %p)\n", Con);

    if (Con != NULL && Con->State == WeaveConnection::kState_Closed)
    {
        printf("  1 remove previous con (currently closed)\n");
        Con->Close();
        Con = NULL;
    }

    // Create a new connection unless there is already one in progress
    // (probably started via an ImageAnnounce notification.)
    if (Con == NULL)
    {
        printf("  2 no existing connection (probably no ImageAnnounce received)\n");
        Con = MessageLayer.NewConnection();
        if (Con == NULL)
        {
            printf("  3 WeaveConnection.Connect failed: no memory\n");
            return;
        }
        Con->OnConnectionComplete = HandleConnectionComplete;
        Con->OnConnectionClosed = HandleConnectionClosed;
        printf("  4 Con: %p\n", Con);

        printf("  5 (DestNodeId: %ld, DestIPAddrStr: %s)\n", (long)DestNodeId, DestIPAddrStr);
        IPAddress::FromString(DestIPAddrStr, DestIPAddr);
        WEAVE_ERROR err = Con->Connect(DestNodeId, kWeaveAuthMode_Unauthenticated, DestIPAddr);
        if (err != WEAVE_NO_ERROR)
        {
            printf("  6 WeaveConnection.Connect failed: %X (%s)\n", err, ErrorStr(err));
            Con->Close();
            Con = NULL;
            return;
        }
    }
    else
    {
        printf("  7 existing connection (probably ImageAnnounce received)\n");
        HandleConnectionComplete(Con, WEAVE_NO_ERROR);
    }

    printf("8 StartClientConnection exiting\n");
}

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 't':
        UseTCP = true;
        break;
    case 'u':
        UseTCP = false;
        break;
    case 'L':
        Listening = true;
        break;
    case 'D':
        DestIPAddrStr = arg;
        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)
    {
        if (argc > 1)
        {
            PrintArgError("%s: Unexpected argument: %s\n", progName, argv[1]);
            return false;
        }

        if (Listening)
        {
            PrintArgError("%s: Please specify either a node id or --listen\n", progName);
            return false;
        }

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

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

    else
    {
        if (!Listening)
        {
            PrintArgError("%s: Please specify either a node id or --listen\n", progName);
            return false;
        }
    }

    return true;
}

void HandleConnectionReceived(WeaveMessageLayer *msgLayer, WeaveConnection *con)
{
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    printf("Connection received from node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);

    con->OnConnectionClosed = HandleConnectionClosed;
    Con = con;
    MIAServer.CreateExchangeCtx(con);
}

void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr)
{
    printf("0 HandleConnectionComplete entering\n");

    WEAVE_ERROR err;
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    if (conErr != WEAVE_NO_ERROR)
    {
        printf("  1 Connection FAILED to node %" PRIX64 " (%s): %s\n", con->PeerNodeId, ipAddrStr, ErrorStr(conErr));
        con->Close();
        Con = NULL;
        return;
    }

    printf("  2 Connection established to node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);

    printf("  4 PacketBuffer for ImageQuery request\n");

    if (Con != NULL)
    {
        printf("  5 Sending TCP ImageQuery request\n");
        err = SWUClient.SendImageQueryRequest(Con);
    }
    else
    {
        char buffer[64];
        printf("  6 (destIPAddr: %s (printed into a string))\n", DestIPAddr.ToString(buffer, strlen(buffer)));
        err = SWUClient.SendImageQueryRequest(DestNodeId, DestIPAddr);
    }
    if (err == WEAVE_NO_ERROR)
    {
        WaitingForSWUResp = true;
    }
    else
    {
        printf("7 SWUClient.SendRequest() failed: %X\n", err);
        Con->Close();
        Con = NULL;
    }

    printf("8 HandleConnectionComplete exiting\n");
}

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

    if (conErr == WEAVE_NO_ERROR)
        printf("Connection closed to node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);
    else
        printf("Connection ABORTED to node %" PRIX64 " (%s): %s\n", con->PeerNodeId, ipAddrStr, ErrorStr(conErr));

    WaitingForSWUResp = false;

    if (Listening)
        con->Close();
    else if (con == Con)
    {
        con->Close();
        Con = NULL;
    }
}
