/*
 *
 *    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 server for the Weave Software Update (SWU) profile.
 *
 */

#define __STDC_FORMAT_MACROS
#define __STDC_LIMIT_MACROS

#include <inttypes.h>
#include <stdlib.h>

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

using namespace nl::Weave;
using namespace nl::Inet;

#define TOOL_NAME "weave-swu-server"

static bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg);
static bool ParseStringToUint8_List(char const *aString, char const *aDelim, uint8_t *aList, uint8_t *aListSize);
static void HandleConnectionReceived(WeaveMessageLayer *msgLayer, WeaveConnection *con);
static void HandleSecureSessionEstablished(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, uint16_t sessionKeyId, uint64_t peerNodeId, uint8_t encType);
static void HandleSecureSessionError(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, WEAVE_ERROR localErr, uint64_t peerNodeId, StatusReport *statusReport);
static void HandleConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr);
static void GenerateReferenceImageQuery(ImageQuery *aImageQuery);
static void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);
static void StartServerConnection();

MockSoftwareUpdateServer MockSWUServer;

uint16_t ProductId              = 1;
uint16_t ProductRev             = 1;
uint16_t VendorId               = kWeaveVendor_NestLabs;
const char *gSoftwareVersion            = "1";
const char *gUpdateSchemeList   = "3";
const char *gIntegrityTypeList  = "0";
const char *gFileDesignator     = NULL;
bool gListening                 = false;
const char *gDestAddrStr        = NULL;
const char *gDestNodeIdStr      = NULL;
IPAddress gDestIPAddr;
WeaveConnection *Con            = NULL;
static uint64_t gDestNodeId     = 1;
bool gUseTCP                     = true;

enum
{
    kToolOpt_SoftwareVersion = 1000,
    kToolOpt_ProductId,
    kToolOpt_ProductRev,
    kToolOpt_VendorId,
    kToolOpt_IntegrityType,
    kToolOpt_UpdateScheme,
    kToolOpt_FileDesignator,
    kToolOpt_Listen,
    kToolOpt_DestAddr,
    kToolOpt_DestNodeId,
    kToolOpt_UseTCP,
    kToolOpt_UseUDP
};

static OptionDef gToolOptionDefs[] =
{
    { "sw-version",      kArgumentRequired, kToolOpt_SoftwareVersion  },
    { "product-id",      kArgumentRequired, kToolOpt_ProductId        },
    { "product-rev",     kArgumentRequired, kToolOpt_ProductRev       },
    { "vendor-id",       kArgumentRequired, kToolOpt_VendorId         },
    { "integrity-type",  kArgumentRequired, kToolOpt_IntegrityType    },
    { "update-scheme",   kArgumentRequired, kToolOpt_UpdateScheme     },
    { "file-designator", kArgumentRequired, kToolOpt_FileDesignator   },
    { "listen",          kNoArgument,       kToolOpt_Listen           },
    { "dest-addr",       kArgumentRequired, kToolOpt_DestAddr         },
    { "dest-node-id",    kArgumentRequired, kToolOpt_DestNodeId       },
    { "tcp",             kNoArgument,       kToolOpt_UseTCP           },
    { "udp",             kNoArgument,       kToolOpt_UseUDP           },
    { }
};

static const char *gToolOptionHelp =
    " The following arguments are required : \n"
    "\n"
    " --vendor-id <num>\n"
    "       Unique vendor identifier of the sending device\n"
    "       Default is set to 0x235A -> NestLabs\n"
    "\n"
    " --sw-version <version>\n"
    "       Software version that will be compared against the version reported\n"
    "       through the image query. Default is 1.\n"
    "\n"
    " --product-id <num>\n"
    "       Product Id  is the vendor’s unique hardware product identity\n"
    "       of the sending device. Default is 1.\n"
    "\n"
    " --product-rev <num>\n"
    "       Vendor’s product’s hardware revision number of the sending device\n"
    "       Default is set to 1.\n"
    "\n"
    " --integrity-type <num>\n"
    "       Integrity type supported by the sending device\n"
    "       Default is set to 0 -> SHA512\n"
    "       0 -> SHA160 160-bit Secure Hash, aka SHA-1, required\n"
    "       1 -> SHA256 256-bit Secure Hash (SHA-2)\n"
    "       2 -> SHA512 512-bit, Secure Hash (SHA-2)\n"
    "\n"
    " --update-scheme <num>\n"
    "       Update schemes supported by the sending device\n"
    "       Default is set to 3 -> BDX\n"
    "       0 -> HTTP\n"
    "       1 -> HTTPS\n"
    "       2 -> SFTP\n"
    "       3 -> BDX Nest Weave download protocol\n"
     "\n"
    " --file-designator <string>\n"
    "       Path to the image file that is returned to the query\n"
    "       when an update is available. The path must be valid.\n"
    "\n"
    "  --tcp\n"
    "       Use TCP to send SWU Image Announce messages. This is the default.\n"
    "\n"
    "  --udp\n"
    "       Use UDP to send SWU Image Announce messages.\n"
    "\n"
    " --listen\n"
    "       Listen and respond to image request sent from another node.\n"
    "       Otherwise, Send Image Announce notification firstly.\n"
    "\n"
    "  --dest-addr <host>[:<port>]\n"
    "       Send an Image Announce notification 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, image announce\n"
    "       will be sent to the specified port.\n"
    "\n"
    "  --dest-node-id\n"
    "       Send an Image Announce notification to a specific node id."
    "\n";

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

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

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

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case kToolOpt_SoftwareVersion:
        gSoftwareVersion = arg;
        break;
    case kToolOpt_ProductId:
        if (!ParseInt(arg, ProductId))
        {
            PrintArgError("%s: Invalid value specified for product-id: %s\n", progName, arg);
            return false;
        }
        break;
    case kToolOpt_ProductRev:
        if (!ParseInt(arg, ProductRev))
        {
            PrintArgError("%s: Invalid value specified for product-rev: %s\n", progName, arg);
            return false;
        }
        break;
    case kToolOpt_VendorId:
        if (!ParseInt(arg, VendorId))
        {
            PrintArgError("%s: Invalid value specified for vendor-id: %s\n", progName, arg);
            return false;
        }
        break;
    case kToolOpt_IntegrityType:
        gIntegrityTypeList = arg;
        break;
    case kToolOpt_UpdateScheme:
        gUpdateSchemeList = arg;
        break;
    case kToolOpt_FileDesignator:
        gFileDesignator = arg;
        break;
    case kToolOpt_UseTCP:
        gUseTCP = true;
        break;
    case kToolOpt_UseUDP:
        gUseTCP = false;
        break;
    case kToolOpt_Listen:
        gListening = true;
        break;
    case kToolOpt_DestAddr:
        gDestAddrStr = arg;
        break;
    case kToolOpt_DestNodeId:
        gDestNodeIdStr = arg;
        if (!ParseNodeId(gDestNodeIdStr, gDestNodeId))
        {
            PrintArgError("%s: Invalid value specified for destination node-id: %s\n", progName, gDestNodeIdStr);
            return false;
        }
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

void GenerateReferenceImageQuery(ImageQuery *aImageQuery)
{
    ProductSpec productSpec(VendorId,
                            ProductId,
                            ProductRev);

    ReferencedString versionString;
    versionString.init((uint8_t)strlen(gSoftwareVersion), (char *)gSoftwareVersion);

    IntegrityTypeList aTypeList;
    if (!ParseStringToUint8_List((char const *)gIntegrityTypeList, ",", aTypeList.theList, &aTypeList.theLength))
        exit(EXIT_FAILURE);

    UpdateSchemeList aSchemeList;
    if (!ParseStringToUint8_List((char const *)gUpdateSchemeList, ",", aSchemeList.theList, &aSchemeList.theLength))
        exit(EXIT_FAILURE);

    aImageQuery->init(productSpec, versionString, aTypeList, aSchemeList,
                    NULL /*package*/, NULL /*locale*/, 0 /*target node id*/, NULL /*metadata*/);
}

void StartServerConnection()
{
    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)gDestNodeId, gDestAddrStr);
        IPAddress::FromString(gDestAddrStr, gDestIPAddr);
        WEAVE_ERROR err = Con->Connect(gDestNodeId, kWeaveAuthMode_Unauthenticated, gDestIPAddr);
        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");
}

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

    if ((gListening && gDestNodeIdStr != NULL) || (!gListening && gDestNodeIdStr == NULL))
    {
        printf("Please specify either a node id or --listen\n");
        exit(EXIT_FAILURE);
    }

    InitSystemLayer();

    InitNetwork();

    InitWeaveStack(true, true);

    PrintNodeConfig();

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

    SecurityMgr.OnSessionEstablished = HandleSecureSessionEstablished;
    SecurityMgr.OnSessionError = HandleSecureSessionError;

    printf("\nUsing the following configuration:\n");
    printf("  Vendor Id: %d\n", VendorId);
    printf("  Product Id: %d\n", ProductId);
    printf("  Product Rev: %d\n", ProductRev);
    printf("  Software version: %s\n", gSoftwareVersion);
    printf("  Integrity Type: %s\n", gIntegrityTypeList);
    printf("  Update Scheme: %s\n", gUpdateSchemeList);
    printf("\n");

    ImageQuery imageQuery;
    GenerateReferenceImageQuery(&imageQuery);

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

    MockSWUServer.SetReferenceImageQuery(&imageQuery);
    err = MockSWUServer.SetFileDesignator(gFileDesignator);
    if (err != WEAVE_NO_ERROR)
    {
        printf("Unable to open file: %s\n", gFileDesignator);
        printf("Make sure that the path exists and the file is valid\n");
        exit(EXIT_FAILURE);
    }

    if (gListening)
    {
        printf("Listening for Software Update requests...\n");
    }
    else
    {
        printf("Starting the TCP connection...\n");
        if (gUseTCP)
        {
            StartServerConnection();
        }
        else
        {
            err = MockSWUServer.SendImageAnnounce(gDestNodeId, gDestIPAddr);
            if (err != WEAVE_NO_ERROR)
            {
                printf("Software Update Server::SendImageAnnounce failed: %s\n", ErrorStr(err));
                return 0;
            }
        }
    }

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

        ServiceNetwork(sleepTime);
    }

    MockSWUServer.Shutdown();
    ShutdownWeaveStack();
    ShutdownNetwork();
    ShutdownSystemLayer();

    return EXIT_SUCCESS;
}

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

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

    if (Con != NULL)
    {
        printf("  3 Sending TCP Image Announce\n");
        err = MockSWUServer.SendImageAnnounce(Con);
        if (err != WEAVE_NO_ERROR)
        {
            printf("  4 Software Update Server::SendImageAnnounce failed: %s\n", ErrorStr(err));
            return;
        }
    }
    else
    {
        char buffer[64];
        printf("  5 (destIPAddr: %s (printed into a string))\n", gDestIPAddr.ToString(buffer, strlen(buffer)));
        err = MockSWUServer.SendImageAnnounce(gDestNodeId, gDestIPAddr);
        if (err != WEAVE_NO_ERROR)
        {
            printf("  6 Software Update Server::SendImageAnnounce failed: %s\n", ErrorStr(err));
            return;
        }
    }

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

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 HandleSecureSessionEstablished(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, uint16_t sessionKeyId, uint64_t peerNodeId, uint8_t encType)
{
    char ipAddrStr[64];

    if (con)
        con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
    else
        gDestIPAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    printf("Secure session established with node %" PRIX64 " (%s)\n", peerNodeId, ipAddrStr);
}

void HandleSecureSessionError(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, WEAVE_ERROR localErr, uint64_t peerNodeId, StatusReport *statusReport)
{
    char ipAddrStr[64];

    if (con)
    {
        con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
        con->Close();
    }
    else
        gDestIPAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    if (localErr == WEAVE_ERROR_STATUS_REPORT_RECEIVED && statusReport != NULL)
        printf("FAILED to establish secure session with node %" PRIX64 " (%s): %s\n", peerNodeId, ipAddrStr, nl::StatusReportStr(statusReport->mProfileId, statusReport->mStatusCode));
    else
        printf("FAILED to establish secure session with node %" PRIX64 " (%s): %s\n", peerNodeId, ipAddrStr, ErrorStr(localErr));
}

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

    con->Close();
}

bool ParseStringToUint8_List(char const *aString, char const *aDelim, uint8_t *aList, uint8_t *aListSize)
{
    char *token = NULL;
    int index = 0;

    if (aDelim == NULL || aString == NULL || aListSize == 0 || aList == NULL)
        return false;

    char *aDelimitedList = (char *) malloc (strlen(aString) + 1);
    strcpy(aDelimitedList, aString);

    token = strtok(aDelimitedList, aDelim);
    while (token != NULL) {
        aList[index] = strtoul(token, NULL, 10);
        token = strtok(NULL, aDelim);
        index++;
    }

    *aListSize = index;

    free(aDelimitedList);

    return true;
}
