/*
 *
 *    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 Bulk Data Transfer (BDX) profile.
 *
 */

#define __STDC_FORMAT_MACROS

#include <inttypes.h>

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

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

#define TOOL_NAME "weave-bdx-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);

const char *DestIPAddrStr = NULL;
const char *DestFileName = NULL;
BulkDataTransferClient BDXClient;
bool ClientConEstablished = false;
bool DestHostNameResolved = false;  // only used for UDP

//Globals used by BDX-client
bool WaitingForBDXResp = false;
uint64_t DestNodeId = 1;
IPAddress DestIPAddr;
WeaveConnection *Con = NULL;

static OptionDef gToolOptionDefs[] =
{
    { "output-file", kArgumentRequired, 'o' },
    { "dest-addr",   kArgumentRequired, 'D' },
    { }
};

static const char *gToolOptionHelp =
    "  -o, --output-file <filename>\n"
    "       File to which bulk data will be written. Bulk data not written to disk\n"
    "       by default. Accepts paths relative to current working directory.\n"
    "\n"
    "  -D, --dest-addr <ip-addr>\n"
    "       Send ReceiveInit requests to a specific address rather than one\n"
    "       derived from the destination node id.  <ip-addr> can be an IPv4\n"
    "       address or an IPv6 address.\n"
    "\n";

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

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options...>] <dest-node-id>[@<dest-ip-addr>\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT
);

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

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

    InitToolCommon();

    SetupFaultInjectionContext(argc, argv);
    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(false, true);

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

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

    PrintNodeConfig();

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

    //Set up connection and connect callbacks to handle success/failure cases
    StartClientConnection();

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

        ServiceNetwork(sleepTime);
    }

    BDXClient.Shutdown();
    ShutdownWeaveStack();

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

    // Do nothing if a connect attempt is already in progress.
    if (Con != NULL)
    {
        printf("@@@ 2 (Con: %p) previous Con likely hanging\n", Con);
        return;
    }

    Con = MessageLayer.NewConnection();
    if (Con == NULL)
    {
        printf("@@@ 3 WeaveConnection.Connect failed: no memory\n");
        return;
    }
    printf("@@@ 3+ (Con: %p)\n", Con);
    Con->OnConnectionComplete = HandleConnectionComplete;
    Con->OnConnectionClosed = HandleConnectionClosed;

    printf("@@@ 3++ (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("@@@ 4 WeaveConnection.Connect failed: %X (%s)\n", err, ErrorStr(err));
        Con->Close();
        Con = NULL;
        return;
    }

    BDXClient.setCon(Con);

    printf("@@@ 5 StartClientConnection exiting\n");
}

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 'o':
        DestFileName = arg;
        break;
    case 'S':
        UsePASE = 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 < 1)
    {
        PrintArgError("%s: Please specify either the 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 *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;
    }

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

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

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

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

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

    ClientConEstablished = true;

    PacketBuffer *payloadBuf = PacketBuffer::New();
    if (payloadBuf == NULL)
    {
        printf("@@@ 3 Unable to allocate PacketBuffer\n");
        return;
    }

    //Send the ReceiveInit request
    if (Con != NULL)
    {
        printf("@@@ 4 Sending TCP bdx request\n");
        err = BDXClient.SendReceiveInitRequest(Con);
    }
    else
    {
        char buffer[64];
        printf("@@@ 5 (destIPAddr: %s (printed into a string))\n", DestIPAddr.ToString(buffer, strlen(buffer)));
        err = BDXClient.SendReceiveInitRequest(DestNodeId, DestIPAddr);
    }
    if (err == WEAVE_NO_ERROR)
    {
        WaitingForBDXResp = true;
    }
    else
    {
        printf("@@@ 6 BDXClient.SendRequest() failed: %X\n", err);
        Con->Close();
        Con = NULL;
    }

    printf("@@@ 7 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));

    WaitingForBDXResp = false;

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