/*
 *
 *    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' },
    { "pairing-code",       kArgumentRequired, 'P' },
    { "software-version",   kArgumentRequired, 'n' },
    { "tlv",                kNoArgument,       'T' },
    { NULL }
};

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"
    "       The SSID 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':
        if (strlen(arg) > WeaveDeviceDescriptor::kMaxRendezvousWiFiESSID)
        {
            PrintArgError("%s: Invalid value specified for device rendezvous WiFi SSID: %s\n", progName, arg);
            return false;
        }
        strcpy(DeviceDesc.RendezvousWiFiESSID, arg);
        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\n", prefix, 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);
}
