/*
 *
 *    Copyright (c) 2014-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 the Weave Mock Weave Border Gateway.
 *
 *      This is used to instantiate a Tunnel Agent which opens a
 *      tunnel endpoint and forwards IPv6 packets between the
 *      Service connection and the tunnel endpoint.
 *
 */

#define __STDC_FORMAT_MACROS

#define DEFAULT_BG_NODE_ID 0xBADCAFE

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

#include "ToolCommon.h"
#include "CASEOptions.h"
#include <Weave/Support/logging/DecodedIPPacket.h>
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelAgent.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelCommon.h>
#include <InetLayer/InetInterface.h>
#include <Weave/Support/WeaveFaultInjection.h>
#include <Weave/Profiles/device-description/DeviceDescription.h>
#include <Weave/Profiles/vendor/nestlabs/device-description/NestProductIdentifiers.hpp>

#if WEAVE_CONFIG_ENABLE_TUNNELING
using namespace ::nl::Weave::Profiles::WeaveTunnel;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
using namespace ::nl::Weave::Profiles::DeviceDescription;
#endif

#define TOOL_NAME "mock-weave-bg"

#define DEFAULT_TFE_NODE_ID 0xC0FFEE

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 WeaveTunnelAgent gTunAgent;

static bool gUseCASE = false;
static bool gTunnelLogging = false;
static IPAddress gDestAddr = IPAddress::Any;
static uint16_t gDestPort = 0;
static uint64_t gDestNodeId = DEFAULT_TFE_NODE_ID;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
static bool gUseServiceDirForTunnel = false;
static ServiceDirectory::WeaveServiceManager gServiceMgr;
static uint8_t gServiceDirCache[500];
#endif

static uint8_t gRole = kClientRole_BorderGateway; //Default Value

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
static const char *gPrimaryIntf;
static const char *gBackupIntf;
static bool gEnableBackup = false;
#endif

enum
{
    kToolOpt_ConnectTo          = 1000,
    kToolOpt_UseServiceDir,
};

static OptionDef gToolOptionDefs[] =
{
    { "role",                kArgumentRequired, 'r' },
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    { "primary-intf",        kArgumentRequired, 'P' },
    { "backup-intf",         kArgumentRequired, 'B' },
    { "enable-backup",       kNoArgument,       'e' },
#endif
    { "connect-to",          kArgumentRequired, kToolOpt_ConnectTo },
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    { "service-dir",         kNoArgument,       kToolOpt_UseServiceDir },
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    { "case",                kNoArgument,       'C' },
#if WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
    { "tunnel-log",          kNoArgument,       'l' },
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
    { }
};

static const char *const gToolOptionHelp =
    "  -r, --role <num>\n"
    "       Role for local client node, i.e., 1) Border Gateway or 2) Mobile Device.\n"
    "\n"
    "  --connect-to <addr>[:<port>][%<interface>]\n"
    "       Connect to the tunnel service at the supplied address.\n"
    "\n"
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    "  --service-dir\n"
    "       Use service directory to lookup the address of the tunnel server.\n"
    "\n"
#endif // WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    "  -C, --case\n"
    "       Use CASE to create an authenticated session with the tunnel server.\n"
    "\n"
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    "  -P, --primary-intf <interface-name>\n"
    "       Interface name for primary tunnel.\n"
    "\n"
    "  -B, --backup-intf <interface-name>\n"
    "       Interface name for backup tunnel.\n"
    "\n"
    "  -e, --enable-backup\n"
    "       Enable the use of a backup tunnel.\n"
    "\n"
#endif
#if WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
    "  -l, --tunnel-log\n"
    "       Use detailed logging of Tunneled IP packet\n"
    "\n"
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
    "";

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,
    &gWRMPOptions,
    &gCASEOptions,
    &gDeviceDescOptions,
    &gServiceDirClientOptions,
    &gFaultInjectionOptions,
    &gHelpOptions,
    NULL
};

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 'r':
        if (!ParseInt(arg, gRole) ||
            (gRole != kClientRole_BorderGateway && gRole != kClientRole_MobileDevice))
        {
            PrintArgError("%s: Invalid value specified for device role: %s. Possible values: (1)BorderGateway and (2)MobileDevice\n", progName, arg);
            return false;
        }
        break;
#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    case 'P':
        gPrimaryIntf = arg;
        break;
    case 'B':
        gBackupIntf = arg;
        break;
    case 'e':
        gEnableBackup = true;
        break;
#endif // WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    case kToolOpt_ConnectTo:
    {
        const char *host;
        uint16_t hostLen;
        if (ParseHostAndPort(arg, strlen(arg), host, hostLen, gDestPort) != WEAVE_NO_ERROR)
        {
            PrintArgError("%s: Invalid value specified for --connect-to: %s\n", progName, arg);
            return false;
        }
        char *hostCopy = strndup(host, hostLen);
        bool isValidAddr = IPAddress::FromString(hostCopy, gDestAddr);
        free(hostCopy);
        if (!isValidAddr)
        {
            PrintArgError("%s: Invalid value specified for --connect-to (expected IP address): %s\n", progName, arg);
            return false;
        }
        break;
    }
#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    case kToolOpt_UseServiceDir:
        gUseServiceDirForTunnel = true;
        break;
#endif
    case 'C':
        gUseCASE = true;
        break;
    case 'l':
        gTunnelLogging = true;
        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 (!ParseNodeId(argv[0], gDestNodeId))
        {
            PrintArgError("%s: Invalid value specified for destination node-id: %s\n", progName, argv[0]);
            return false;
        }
    }

    return true;
}

#if WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
void TunneledPacketTransitHandler(const PacketBuffer &pkt, TunnelPktDirection pktDir, TunnelType tunnelType, bool &toDrop)
{
    DecodedIPPacket decodedPkt;
    char InOrOut[9];
    char tunTypeStr[9];

    // Decode the packet; skip the tunnel header and pass the IP packet

    decodedPkt.PacketHeaderDecode(pkt.Start() + TUN_HDR_SIZE_IN_BYTES, pkt.DataLength() - TUN_HDR_SIZE_IN_BYTES);

    strncpy(InOrOut, (pktDir == kDir_Outbound) ? "Outbound" : "Inbound", sizeof(InOrOut));
    strncpy(tunTypeStr, (tunnelType == kType_TunnelPrimary) ? "primary" : (tunnelType == kType_TunnelBackup) ? "backup" : "shortcut", sizeof(tunTypeStr));

    WeaveLogDetail(WeaveTunnel, "Tun: %s over %s", InOrOut, tunTypeStr);

    // Log the header fields

    LogPacket(decodedPkt, true);

    // Inject a packet drop by the application.
    WEAVE_FAULT_INJECT(FaultInjection::kFault_TunnelPacketDropByPolicy,
                       toDrop = true);

}
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK

#endif // WEAVE_CONFIG_ENABLE_TUNNELING

int main(int argc, char *argv[])
{
#if WEAVE_CONFIG_ENABLE_TUNNELING
    WEAVE_ERROR err;
    gWeaveNodeOptions.LocalNodeId = DEFAULT_BG_NODE_ID;
    WeaveAuthMode authMode = kWeaveAuthMode_Unauthenticated;

    nl::Weave::System::Stats::Snapshot before;
    nl::Weave::System::Stats::Snapshot after;
    const bool printStats = true;

    InitToolCommon();

    SetupFaultInjectionContext(argc, argv);
    UseStdoutLineBuffering();
    SetSignalHandler(DoneOnHandleSIGUSR1);

    // Configure some alternate defaults for the device descriptor values.
    gDeviceDescOptions.BaseDeviceDesc.ProductId = nl::Weave::Profiles::Vendor::Nestlabs::DeviceDescription::kNestWeaveProduct_Topaz2;
    strcpy(gDeviceDescOptions.BaseDeviceDesc.SerialNumber, "mock-weave-bg");
    strcpy(gDeviceDescOptions.BaseDeviceDesc.SoftwareVersion, "mock-weave-bg/1.0");
    gDeviceDescOptions.BaseDeviceDesc.DeviceFeatures = WeaveDeviceDescriptor::kFeature_LinePowered;

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

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDirForTunnel && gDestAddr != IPAddress::Any)
    {
        printf("ERROR: Please specify only one of --connect-to or --service-dir\n");
        exit(EXIT_FAILURE);
    }
    if (!gUseServiceDirForTunnel && gDestAddr == IPAddress::Any)
    {
        printf("ERROR: Please specify how to find the tunnel server using either --connect-to or --service-dir\n");
        exit(EXIT_FAILURE);
    }
#else
    if (gDestAddr == IPAddress::Any)
    {
        printf("ERROR: Please specify the address of the tunnel server using --connect-to\n");
        exit(EXIT_FAILURE);
    }
#endif

    InitSystemLayer();

    InitNetwork();

    InitWeaveStack(false, true);

    printf("Weave Node Configuration:\n");
    printf("  Fabric Id: %" PRIX64 "\n", FabricState.FabricId);
    printf("  Subnet Number: %X\n", FabricState.DefaultSubnet);
    printf("  Node Id: %" PRIX64 "\n", FabricState.LocalNodeId);

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

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    err = gServiceMgr.init(&ExchangeMgr, gServiceDirCache, sizeof(gServiceDirCache),
            GetRootServiceDirectoryEntry, kWeaveAuthMode_CASE_ServiceEndPoint,
            NULL, NULL, OverrideServiceConnectArguments);
    FAIL_ERROR(err, "gServiceMgr.Init failed");
#endif

    if (gUseCASE)
        authMode = kWeaveAuthMode_CASE_AnyCert;

#if WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
    if (gUseServiceDirForTunnel)
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId,
                            authMode, &gServiceMgr,
                            "weave-tun0", gRole);
    }
    else
#endif
    {
        err = gTunAgent.Init(&Inet, &ExchangeMgr, gDestNodeId, gDestAddr,
                            authMode,
                            "weave-tun0", gRole);
    }

    FAIL_ERROR(err, "TunnelAgent.Init failed");

    if (gDestAddr != IPAddress::Any)
    {
        gTunAgent.SetDestination(gDestNodeId, gDestAddr, gDestPort);
    }

#if WEAVE_CONFIG_TUNNEL_FAILOVER_SUPPORTED
    if (gPrimaryIntf)
    {
        gTunAgent.SetPrimaryTunnelInterface(gPrimaryIntf);
    }

    if (gBackupIntf)
    {
        gTunAgent.SetBackupTunnelInterface(gBackupIntf);
    }

    if (gEnableBackup)
    {
        gTunAgent.EnableBackupTunnel();
    }
#endif

#if WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK
    if (gTunnelLogging)
    {
        gTunAgent.OnTunneledPacketTransit = TunneledPacketTransitHandler;
    }
    else
    {
        gTunAgent.OnTunneledPacketTransit = NULL;
    }
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TRANSIT_CALLBACK

    err = gTunAgent.StartServiceTunnel();
    FAIL_ERROR(err, "TunnelAgent.StartServiceTunnel failed");

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

        ServiceNetwork(sleepTime);

    }

    if (gSigusr1Received) {
        printf("SIGUSR1 received: proceed to exit gracefully\n");
    }

    gTunAgent.StopServiceTunnel();
    gTunAgent.Shutdown();

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

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

#endif // WEAVE_CONFIG_ENABLE_TUNNELING
    return EXIT_SUCCESS;
}
