/*
 *
 *    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 command line utility for encoding and
 *      decoding Weave Device Descriptors.
 *
 *      Please see the document "Nest Weave: Factory Provisioning
 *      Specification" for more information about the format of the
 *      Nest Weave Device Descriptor.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include <libgen.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <inttypes.h>

#include "ToolCommon.h"
#include <Weave/WeaveVersion.h>
#include <Weave/Core/WeaveEncoding.h>
#include <Weave/Profiles/device-description/DeviceDescription.h>

using namespace nl::Weave::Profiles;
using namespace nl::Weave::Profiles::DeviceDescription;
using namespace nl::Weave::Encoding;

#define TOOL_NAME "weave-device-descriptor"

#define COPYRIGHT_STRING "Copyright (c) 2013-2017 Nest Labs, Inc.\nAll rights reserved.\n"

static bool HandleEncodeOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg);
static bool HandleDecodeArg(const char *progName, int argc, char *argv[]);
static bool ParseDate(const char *dateStr, uint16_t& year, uint8_t& month, uint8_t& day);
static void PrintDeviceDescriptor(const WeaveDeviceDescriptor& deviceDesc, const char *prefix);

static HelpOptions gGeneralHelpOptions(
    TOOL_NAME,
    "Usage: weave-device-descriptor <operation> [<options...>]\n",
    WEAVE_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Tool for encoding and decoding Weave device descriptors.\n"
    "\n"
    "OPERATIONS:\n"
    "\n"
    "  encode\n"
    "       Encode a weave device descriptor given information supplied on\n"
    "       the command line.\n"
    "\n"
    "  decode\n"
    "       Decode and print a weave device descriptor read from stdin.\n"
    "\n"
    "Type 'weave-device-descriptor <operation> --help' for help on a particular\n"
    "operation.\n"
    "\n"
);

static OptionSet *gToolOptionSets[] =
{
    &gGeneralHelpOptions,
    NULL
};

static OptionDef gEncodeOptionDefs[] =
{
    { "vendor",             kArgumentRequired, 'V' },
    { "product",            kArgumentRequired, 'p' },
    { "revision",           kArgumentRequired, 'r' },
    { "mfg-date",           kArgumentRequired, 'm' },
    { "802-15-4-mac",       kArgumentRequired, '8' },
    { "wifi-mac",           kArgumentRequired, 'w' },
    { "serial-num",         kArgumentRequired, 's' },
    { "device-id",          kArgumentRequired, 'd' },
    { "ssid",               kArgumentRequired, 'S' },
    { "ssid-suffix",        kArgumentRequired, 'H' },
    { "pairing-code",       kArgumentRequired, 'P' },
    { "software-version",   kArgumentRequired, 'n' },
    { "tlv",                kNoArgument,       'T' },
    { }
};

static const char *const gEncodeOptionHelp =
    "  -V, --vendor <num> | nest\n"
    "       The device vendor id, or 'nest' for the Nest vendor id.\n"
    "\n"
    "  -p, --product <num>\n"
    "       The device product id.\n"
    "\n"
    "  -r, --revision <num>\n"
    "       The device revision number.\n"
    "\n"
    "  -s, --serial-num <string>\n"
    "       The device's serial number.\n"
    "\n"
    "  -d, --device-id <hex-string>\n"
    "       The device's Weave node id, given as a hex string.\n"
    "\n"
    "  -m, --mfg-date <YYYY>/<MM>/<DD> | <YYYY>/<MM>\n"
    "       The device manufacturing date.\n"
    "\n"
    "  -n, --software-version <string>\n"
    "       The device's software version. Note that this field is not supported in\n"
    "       the text form of a device descriptor.\n"
    "\n"
    "  -8, --802-15-4-mac <mac>\n"
    "       The device's 802.15.4 MAC address given as a hex string (colons optional).\n"
    "\n"
    "  -w, --wifi-mac <mac>\n"
    "       The device's 802.11 MAC address given as a hex string (colons optional).\n"
    "\n"
    "  -S, --ssid <string>\n"
    "  -H, --ssid-suffix <string>\n"
    "       The SSID or SSID suffix for the device's WiFi rendezvous network.\n"
    "\n"
    "  -P, --pairing-code <string>\n"
    "       The device's pairing code.\n"
    "\n"
    "  -T, --tlv\n"
    "       Encode the descriptor in TLV format, instead of text format.\n"
    "\n";

static OptionSet gEncodeOptions =
{
    HandleEncodeOption,
    gEncodeOptionDefs,
    "ENCODE OPTIONS",
    gEncodeOptionHelp,
};

static HelpOptions gEncodeHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " encode [<options...>]\n",
    WEAVE_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Encode a weave device descriptor given information supplied on the command line.\n"
);

static OptionSet *gEncodeOptionSets[] =
{
    &gEncodeOptions,
    &gEncodeHelpOptions,
    NULL
};

static HelpOptions gDecodeHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " decode [<options...>]\n"
    "       " TOOL_NAME " decode [<options...>] <text-device-descriptor>\n",
    WEAVE_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Decode and print a weave device descriptor read from stdin or the command line.\n"
);

static OptionSet *gDecodeOptionSets[] =
{
    &gDecodeHelpOptions,
    NULL
};

const char *Operation = NULL;
WeaveDeviceDescriptor DeviceDesc;
bool UseTLV = false;
const char *DecodeArg = NULL;

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

    nl::Weave::Logging::SetLogFilter(nl::Weave::Logging::kLogCategory_None);

    InitToolCommon();

    if (argc < 2)
    {
        gGeneralHelpOptions.PrintBriefUsage(stderr);
        exit(EXIT_FAILURE);
    }

    if (strcmp(argv[1], "encode") == 0)
    {
        uint8_t encodeBuf[128];
        uint32_t encodedLen;

        argv[1] = argv[0];

        if (!ParseArgs(TOOL_NAME "(encode)", argc-1, argv+1, gEncodeOptionSets))
        {
            exit(EXIT_FAILURE);
        }

        if (UseTLV)
            err = WeaveDeviceDescriptor::EncodeTLV(DeviceDesc, encodeBuf, sizeof(encodeBuf), encodedLen);
        else
            err = WeaveDeviceDescriptor::EncodeText(DeviceDesc, (char *)encodeBuf, sizeof(encodeBuf), encodedLen);
        FAIL_ERROR(err, "Encode failed");

        if (write(STDOUT_FILENO, encodeBuf, (size_t)encodedLen) != (ssize_t)encodedLen ||
            (!UseTLV && write(STDOUT_FILENO, "\n", 1) != 1))
        {
            perror("Output error");
            exit(EXIT_FAILURE);
        }
    }

    else if (strcmp(argv[1], "decode") == 0)
    {
        static uint8_t readBuf[2048];
        uint32_t lenRead = 0;
        uint32_t encodedLen;
        int readRes;

        argv[1] = argv[0];

        if (!ParseArgs(TOOL_NAME "(decode)", argc-1, argv+1, gDecodeOptionSets, HandleDecodeArg))
        {
            exit(EXIT_FAILURE);
        }

        if (DecodeArg != NULL)
        {
            strncpy((char *)readBuf, DecodeArg, sizeof(readBuf));
            encodedLen = strlen(DecodeArg);
        }

        else
        {
            while ((readRes = read(STDIN_FILENO, readBuf + lenRead, sizeof(readBuf) - lenRead)) > 0) {
                lenRead += readRes;
                if (lenRead == sizeof(readBuf))
                {
                    fprintf(stderr, "Input too long.\n");
                    exit(EXIT_FAILURE);
                }
            }
            if (readRes < 0)
            {
                perror("Input error");
                exit(EXIT_FAILURE);
            }

            encodedLen = lenRead;
        }

        err = WeaveDeviceDescriptor::Decode(readBuf, encodedLen, DeviceDesc);
        FAIL_ERROR(err, "Decode failed");

        PrintDeviceDescriptor(DeviceDesc, "");
    }

    else
    {
        if (!ParseArgs(TOOL_NAME, argc, argv, gToolOptionSets))
        {
            exit(EXIT_FAILURE);
        }
    }

    return EXIT_SUCCESS;
}

bool HandleEncodeOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    int32_t val;
    uint32_t len;

    switch (id)
    {
    case 'V':
        if (!ParseInt(arg, val, 0) || val < 0 || val > UINT16_MAX)
        {
            if (strcasecmp(arg, "nest") == 0 || strcasecmp(arg, "nestlabs") == 0)
            {
                val = kWeaveVendor_NestLabs;
            }
            else
            {
                PrintArgError("%s: Invalid value specified for vendor id: %s\n", progName, arg);
                return false;
            }
        }
        DeviceDesc.VendorId = val;
        break;
    case 'p':
        if (!ParseInt(arg, val, 0) || val < 0 || val > UINT16_MAX)
        {
            PrintArgError("%s: Invalid value specified for product id: %s\n", progName, arg);
            return false;
        }
        DeviceDesc.ProductId = val;
        break;
    case 'r':
        if (!ParseInt(arg, val, 0) || val < 0 || val > UINT16_MAX)
        {
            PrintArgError("%s: Invalid value specified for product revision: %s\n", progName, arg);
            return false;
        }
        DeviceDesc.ProductRevision = val;
        break;
    case 'm':
        if (!ParseDate(arg, DeviceDesc.ManufacturingDate.Year, DeviceDesc.ManufacturingDate.Month, DeviceDesc.ManufacturingDate.Day))
        {
            PrintArgError("%s: Invalid value specified for manufacturing date: %s\n", progName, arg);
            return false;
        }
        break;
    case '8':
        if (!ParseHexString(arg, strlen(arg), DeviceDesc.Primary802154MACAddress, 8, len) || len != 8)
        {
            PrintArgError("%s: Invalid value specified for 802.15.4 MAC address: %s\n", progName, arg);
            return false;
        }
        break;
    case 'w':
        if (!ParseHexString(arg, strlen(arg), DeviceDesc.PrimaryWiFiMACAddress, 6, len) || len != 6)
        {
            PrintArgError("%s: Invalid value specified for 802.15.4 MAC address: %s\n", progName, arg);
            return false;
        }
        break;
    case 's':
        if (strlen(arg) > WeaveDeviceDescriptor::kMaxSerialNumberLength)
        {
            PrintArgError("%s: Invalid value specified for device serial number: %s\n", progName, arg);
            return false;
        }
        strcpy(DeviceDesc.SerialNumber, arg);
        break;
    case 'n':
        if (strlen(arg) > WeaveDeviceDescriptor::kMaxSoftwareVersionLength)
        {
            PrintArgError("%s: Invalid value specified for device software version: %s\n", progName, arg);
            return false;
        }
        strcpy(DeviceDesc.SoftwareVersion, arg);
        break;
    case 'd':
    {
        union
        {
            uint64_t deviceId;
            uint8_t deviceIdBytes[8];
        };

        if (!ParseHexString(arg, strlen(arg), deviceIdBytes, sizeof(deviceIdBytes), len) || len != sizeof(deviceIdBytes))
        {
            PrintArgError("%s: Invalid value specified for device id: %s\n", progName, arg);
            return false;
        }
        DeviceDesc.DeviceId = BigEndian::HostSwap64(deviceId);
        break;
    }
    case 'S':
    case 'H':
        if (strlen(arg) > WeaveDeviceDescriptor::kMaxRendezvousWiFiESSID)
        {
            PrintArgError("%s: Invalid value specified for device rendezvous WiFi SSID or SSID suffix: %s\n", progName, arg);
            return false;
        }
        strcpy(DeviceDesc.RendezvousWiFiESSID, arg);
        if (id == 'S')
        {
            DeviceDesc.Flags &= ~WeaveDeviceDescriptor::kFlag_IsRendezvousWiFiESSIDSuffix;
        }
        else
        {
            DeviceDesc.Flags |= WeaveDeviceDescriptor::kFlag_IsRendezvousWiFiESSIDSuffix;
        }
        break;
    case 'P':
        if (strlen(arg) > WeaveDeviceDescriptor::kMaxPairingCodeLength)
        {
            PrintArgError("%s: Invalid value specified for device pairing code: %s\n", progName, arg);
            return false;
        }
        strcpy(DeviceDesc.PairingCode, arg);
        break;
    case 'T':
        UseTLV = true;
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

static bool HandleDecodeArg(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 (strcmp(argv[0], "-") != 0)
        {
            DecodeArg = argv[0];
        }
    }

    return true;
}

bool ParseDate(const char *dateStr, uint16_t& year, uint8_t& month, uint8_t& day)
{
    struct tm date;

    if (strptime(dateStr, "%Y/%m/%d", &date) == NULL)
    {
        if (strptime(dateStr, "%Y/%m", &date) == NULL)
            return false;
        date.tm_mday = 0;
    }

    date.tm_year += 1900;

    if (date.tm_year < 2001 || date.tm_year > 2099)
        return false;

    year = date.tm_year;
    month = date.tm_mon + 1;
    day = date.tm_mday;

    return true;
}

void PrintDeviceDescriptor(const WeaveDeviceDescriptor& deviceDesc, const char *prefix)
{
    if (DeviceDesc.DeviceId != 0)
        printf("%sDevice Id: %016" PRIX64 "\n", prefix, DeviceDesc.DeviceId);
    if (DeviceDesc.FabricId != 0)
        printf("%sFabric Id: %016" PRIX64 "\n", prefix, DeviceDesc.FabricId);
    if (DeviceDesc.VendorId != 0)
        printf("%sVendor Code: %04" PRIX16 "\n", prefix, DeviceDesc.VendorId);
    if (DeviceDesc.ProductId != 0)
        printf("%sProduct Code: %04" PRIX16 "\n", prefix, DeviceDesc.ProductId);
    if (DeviceDesc.ProductRevision != 0)
        printf("%sProduct Revision: %" PRIu16 "\n", prefix, DeviceDesc.ProductRevision);
    if (DeviceDesc.SerialNumber[0] != 0)
        printf("%sSerial Number: %s\n", prefix, DeviceDesc.SerialNumber);
    if (DeviceDesc.SoftwareVersion[0] != 0)
        printf("%sSoftware Version: %s\n", prefix, DeviceDesc.SoftwareVersion);
    if (DeviceDesc.ManufacturingDate.Year != 0 && DeviceDesc.ManufacturingDate.Month != 0)
    {
        printf("%sManufacturing Date: ", prefix);
        printf("%04" PRIu16 "/", DeviceDesc.ManufacturingDate.Year);
        printf("%02" PRIu8 "", DeviceDesc.ManufacturingDate.Month);
        if (DeviceDesc.ManufacturingDate.Day != 0)
            printf("/%02" PRIu8 "\n", DeviceDesc.ManufacturingDate.Day);
        else
            printf("\n");
    }
    if (!IsZeroBytes(DeviceDesc.Primary802154MACAddress, sizeof(DeviceDesc.Primary802154MACAddress)))
    {
        printf("%sPrimary 802.15.4 MAC: ", prefix);
        PrintMACAddress(DeviceDesc.Primary802154MACAddress, sizeof(DeviceDesc.Primary802154MACAddress));
        printf("\n");
    }
    if (!IsZeroBytes(DeviceDesc.PrimaryWiFiMACAddress, sizeof(DeviceDesc.PrimaryWiFiMACAddress)))
    {
        printf("%sPrimary WiFi MAC: ", prefix);
        PrintMACAddress(DeviceDesc.PrimaryWiFiMACAddress, sizeof(DeviceDesc.PrimaryWiFiMACAddress));
        printf("\n");
    }
    if (DeviceDesc.RendezvousWiFiESSID[0] != 0)
        printf("%sRendezvous WiFi SSID%s: %s\n", prefix,
               ((DeviceDesc.Flags & WeaveDeviceDescriptor::kFlag_IsRendezvousWiFiESSIDSuffix) != 0) ? " Suffix" : "",
               DeviceDesc.RendezvousWiFiESSID);
    if (DeviceDesc.PairingCode[0] != 0)
        printf("%sPairing Code: %s\n", prefix, DeviceDesc.PairingCode);
    if (DeviceDesc.PairingCompatibilityVersionMajor != 0)
        printf("%sPairing Compatibility Major Version: %" PRIu16 "\n", prefix, DeviceDesc.PairingCompatibilityVersionMajor);
    if (DeviceDesc.PairingCompatibilityVersionMinor != 0)
        printf("%sPairing Compatibility Minor Version: %" PRIu16 "\n", prefix, DeviceDesc.PairingCompatibilityVersionMinor);
    if (DeviceDesc.DeviceFeatures != 0)
        printf("%sDevice Features: %08" PRIX32 "\n", prefix, DeviceDesc.DeviceFeatures);
}
