/*
 *   Copyright (c) 2020 Project CHIP Authors
 *   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.
 *
 */

#include "Command.h"
#include "CustomStringPrefix.h"
#include "HexConversion.h"
#include "platform/PlatformManager.h"

#include <functional>
#include <netdb.h>
#include <sstream>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>

#include <math.h> // For INFINITY

#include <lib/core/CHIPSafeCasts.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <lib/support/ScopedBuffer.h>
#include <lib/support/StringSplitter.h>
#include <lib/support/logging/CHIPLogging.h>

constexpr char kOptionalArgumentPrefix[]       = "--";
constexpr size_t kOptionalArgumentPrefixLength = 2;

bool Command::InitArguments(int argc, char ** argv)
{
    bool isValidCommand = false;

    size_t argvExtraArgsCount = (size_t) argc;
    size_t mandatoryArgsCount = 0;
    size_t optionalArgsCount  = 0;
    for (auto & arg : mArgs)
    {
        if (arg.isOptional())
        {
            optionalArgsCount++;
        }
        else
        {
            mandatoryArgsCount++;
            argvExtraArgsCount--;
        }
    }

    VerifyOrExit((size_t) (argc) >= mandatoryArgsCount && (argvExtraArgsCount == 0 || (argvExtraArgsCount && optionalArgsCount)),
                 ChipLogError(chipTool, "InitArgs: Wrong arguments number: %d instead of %u", argc,
                              static_cast<unsigned int>(mandatoryArgsCount)));

    // Initialize mandatory arguments
    for (size_t i = 0; i < mandatoryArgsCount; i++)
    {
        char * arg = argv[i];
        if (!InitArgument(i, arg))
        {
            ExitNow();
        }
    }

    // Initialize optional arguments
    // Optional arguments expect a name and a value, so i is increased by 2 on every step.
    for (size_t i = mandatoryArgsCount; i < (size_t) argc; i += 2)
    {
        bool found = false;
        for (size_t j = mandatoryArgsCount; j < mandatoryArgsCount + optionalArgsCount; j++)
        {
            // optional arguments starts with kOptionalArgumentPrefix
            if (strlen(argv[i]) <= kOptionalArgumentPrefixLength &&
                strncmp(argv[i], kOptionalArgumentPrefix, kOptionalArgumentPrefixLength) != 0)
            {
                continue;
            }

            if (strcmp(argv[i] + strlen(kOptionalArgumentPrefix), mArgs[j].name) == 0)
            {
                found = true;

                VerifyOrExit((size_t) argc > (i + 1),
                             ChipLogError(chipTool, "InitArgs: Optional argument %s missing value.", argv[i]));
                if (!InitArgument(j, argv[i + 1]))
                {
                    ExitNow();
                }
            }
        }
        VerifyOrExit(found, ChipLogError(chipTool, "InitArgs: Optional argument %s does not exist.", argv[i]));
    }

    isValidCommand = true;

exit:
    return isValidCommand;
}

static bool ParseAddressWithInterface(const char * addressString, Command::AddressWithInterface * address)
{
    struct addrinfo hints;
    struct addrinfo * result;
    int ret;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family   = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    ret               = getaddrinfo(addressString, nullptr, &hints, &result);
    if (ret < 0)
    {
        ChipLogError(chipTool, "Invalid address: %s", addressString);
        return false;
    }

    if (result->ai_family == AF_INET6)
    {
        struct sockaddr_in6 * addr = reinterpret_cast<struct sockaddr_in6 *>(result->ai_addr);
        address->address           = ::chip::Inet::IPAddress::FromSockAddr(*addr);
        address->interfaceId       = ::chip::Inet::InterfaceId(addr->sin6_scope_id);
    }
#if INET_CONFIG_ENABLE_IPV4
    else if (result->ai_family == AF_INET)
    {
        address->address     = ::chip::Inet::IPAddress::FromSockAddr(*reinterpret_cast<struct sockaddr_in *>(result->ai_addr));
        address->interfaceId = chip::Inet::InterfaceId::Null();
    }
#endif // INET_CONFIG_ENABLE_IPV4
    else
    {
        ChipLogError(chipTool, "Unsupported address: %s", addressString);
        return false;
    }

    return true;
}

// The callback should return whether the argument is valid, for the non-null
// case.  It can't directly write to isValidArgument (by closing over it)
// because in the nullable-and-null case we need to do that from this function,
// via the return value.
template <typename T>
bool HandleNullableOptional(Argument & arg, char * argValue, std::function<bool(T * value)> callback)
{
    if (arg.isOptional())
    {
        if (arg.isNullable())
        {
            arg.value = &(reinterpret_cast<chip::Optional<chip::app::DataModel::Nullable<T>> *>(arg.value)->Emplace());
        }
        else
        {
            arg.value = &(reinterpret_cast<chip::Optional<T> *>(arg.value)->Emplace());
        }
    }

    if (arg.isNullable())
    {
        auto * nullable = reinterpret_cast<chip::app::DataModel::Nullable<T> *>(arg.value);
        if (argValue != nullptr && strncmp(argValue, "null", 4) == 0)
        {
            nullable->SetNull();
            return true;
        }

        arg.value = &(nullable->SetNonNull());
    }

    return callback(reinterpret_cast<T *>(arg.value));
}

bool Command::InitArgument(size_t argIndex, char * argValue)
{
    bool isValidArgument = false;
    bool isHexNotation   = strncmp(argValue, "0x", 2) == 0 || strncmp(argValue, "0X", 2) == 0;

    Argument arg = mArgs.at(argIndex);

    // We have two places where we handle uint8_t-typed args (actual int8u and
    // bool args), so declare the handler function here so it can be reused.
    auto uint8Handler = [&](uint8_t * value) {
        // stringstream treats uint8_t as char, which is not what we want here.
        uint16_t tmpValue;
        std::stringstream ss;
        isHexNotation ? (ss << std::hex << argValue) : (ss << argValue);
        ss >> tmpValue;
        if (chip::CanCastTo<uint8_t>(tmpValue))
        {
            *value = static_cast<uint8_t>(tmpValue);

            uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
            uint64_t max = arg.max;
            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
        }

        return false;
    };

    switch (arg.type)
    {
    case ArgumentType::Complex: {
        // Complex arguments may be optional, but they are not currently supported via the <chip::Optional> class.
        // Instead, they must be explicitly specified as optional using the kOptional flag,
        // and the base TypedComplexArgument<T> class is still referenced.
        auto complexArgument = static_cast<ComplexArgument *>(arg.value);
        return CHIP_NO_ERROR == complexArgument->Parse(arg.name, argValue);
    }

    case ArgumentType::Custom: {
        auto customArgument = static_cast<CustomArgument *>(arg.value);
        return CHIP_NO_ERROR == customArgument->Parse(arg.name, argValue);
    }

    case ArgumentType::VectorString: {
        std::vector<std::string> vectorArgument;

        chip::StringSplitter splitter(argValue, ',');
        chip::CharSpan value;

        while (splitter.Next(value))
        {
            vectorArgument.push_back(std::string(value.data(), value.size()));
        }

        if (arg.flags == Argument::kOptional)
        {
            auto argument = static_cast<chip::Optional<std::vector<std::string>> *>(arg.value);
            argument->SetValue(vectorArgument);
        }
        else
        {
            auto argument = static_cast<std::vector<std::string> *>(arg.value);
            *argument     = vectorArgument;
        }
        return true;
    }
    case ArgumentType::VectorBool: {
        // Currently only chip::Optional<std::vector<bool>> is supported.
        if (arg.flags != Argument::kOptional)
        {
            return false;
        }

        std::vector<bool> vectorArgument;
        std::stringstream ss(argValue);
        while (ss.good())
        {
            std::string valueAsString;
            getline(ss, valueAsString, ',');

            if (strcasecmp(valueAsString.c_str(), "true") == 0)
            {
                vectorArgument.push_back(true);
            }
            else if (strcasecmp(valueAsString.c_str(), "false") == 0)
            {
                vectorArgument.push_back(false);
            }
            else
            {
                return false;
            }
        }

        auto optionalArgument = static_cast<chip::Optional<std::vector<bool>> *>(arg.value);
        optionalArgument->SetValue(vectorArgument);
        return true;
    }

    case ArgumentType::Vector16:
    case ArgumentType::Vector32: {
        std::vector<uint64_t> values;
        uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
        uint64_t max = arg.max;

        std::stringstream ss(argValue);
        while (ss.good())
        {
            std::string valueAsString;
            getline(ss, valueAsString, ',');
            isHexNotation = strncmp(valueAsString.c_str(), "0x", 2) == 0 || strncmp(valueAsString.c_str(), "0X", 2) == 0;

            std::stringstream subss;
            isHexNotation ? subss << std::hex << valueAsString : subss << valueAsString;

            uint64_t value;
            subss >> value;
            VerifyOrReturnError(!subss.fail() && subss.eof() && value >= min && value <= max, false);
            values.push_back(value);
        }

        if (arg.type == ArgumentType::Vector16)
        {
            auto vectorArgument = static_cast<std::vector<uint16_t> *>(arg.value);
            for (uint64_t v : values)
            {
                vectorArgument->push_back(static_cast<uint16_t>(v));
            }
        }
        else if (arg.type == ArgumentType::Vector32 && arg.flags != Argument::kOptional)
        {
            auto vectorArgument = static_cast<std::vector<uint32_t> *>(arg.value);
            for (uint64_t v : values)
            {
                vectorArgument->push_back(static_cast<uint32_t>(v));
            }
        }
        else if (arg.type == ArgumentType::Vector32 && arg.flags == Argument::kOptional)
        {
            std::vector<uint32_t> vectorArgument;
            for (uint64_t v : values)
            {
                vectorArgument.push_back(static_cast<uint32_t>(v));
            }

            auto optionalArgument = static_cast<chip::Optional<std::vector<uint32_t>> *>(arg.value);
            optionalArgument->SetValue(vectorArgument);
        }
        else
        {
            return false;
        }

        return true;
    }

    case ArgumentType::VectorCustom: {
        auto vectorArgument = static_cast<std::vector<CustomArgument *> *>(arg.value);

        std::stringstream ss(argValue);
        while (ss.good())
        {
            std::string valueAsString;
            // By default the parameter separator is ";" in order to not collapse with the argument itself if it contains commas
            // (e.g a struct argument with multiple fields). In case one needs to use ";" it can be overriden with the following
            // environment variable.
            static constexpr char kSeparatorVariable[] = "CHIPTOOL_CUSTOM_ARGUMENTS_SEPARATOR";
            char * getenvSeparatorVariableResult       = getenv(kSeparatorVariable);
            getline(ss, valueAsString, getenvSeparatorVariableResult ? getenvSeparatorVariableResult[0] : ';');

            CustomArgument * customArgument = new CustomArgument();
            vectorArgument->push_back(customArgument);
            VerifyOrReturnError(CHIP_NO_ERROR == vectorArgument->back()->Parse(arg.name, valueAsString.c_str()), false);
        }

        return true;
    }

    case ArgumentType::String: {
        isValidArgument = HandleNullableOptional<char *>(arg, argValue, [&](auto * value) {
            *value = argValue;
            return true;
        });
        break;
    }

    case ArgumentType::CharString: {
        isValidArgument = HandleNullableOptional<chip::CharSpan>(arg, argValue, [&](auto * value) {
            *value = chip::Span<const char>(argValue, strlen(argValue));
            return true;
        });
        break;
    }

    case ArgumentType::OctetString: {
        isValidArgument = HandleNullableOptional<chip::ByteSpan>(arg, argValue, [&](auto * value) {
            // We support two ways to pass an octet string argument.  If it happens
            // to be all-ASCII, you can just pass it in.  Otherwise you can pass in
            // "hex:" followed by the hex-encoded bytes.
            size_t argLen = strlen(argValue);

            if (IsHexString(argValue))
            {
                // Hex-encoded.  Decode it into a temporary buffer first, so if we
                // run into errors we can do correct "argument is not valid" logging
                // that actually shows the value that was passed in.  After we
                // determine it's valid, modify the passed-in value to hold the
                // right bytes, so we don't need to worry about allocating storage
                // for this somewhere else.  This works because the hex
                // representation is always longer than the octet string it encodes,
                // so we have enough space in argValue for the decoded version.
                chip::Platform::ScopedMemoryBuffer<uint8_t> buffer;

                size_t octetCount;
                CHIP_ERROR err = HexToBytes(
                    chip::CharSpan(argValue + kHexStringPrefixLen, argLen - kHexStringPrefixLen),
                    [&buffer](size_t allocSize) {
                        buffer.Calloc(allocSize);
                        return buffer.Get();
                    },
                    &octetCount);
                if (err != CHIP_NO_ERROR)
                {
                    return false;
                }

                memcpy(argValue, buffer.Get(), octetCount);
                *value = chip::ByteSpan(chip::Uint8::from_char(argValue), octetCount);
                return true;
            }

            // Just ASCII.  Check for the "str:" prefix.
            if (IsStrString(argValue))
            {
                // Skip the prefix
                argValue += kStrStringPrefixLen;
                argLen -= kStrStringPrefixLen;
            }
            *value = chip::ByteSpan(chip::Uint8::from_char(argValue), argLen);
            return true;
        });
        break;
    }

    case ArgumentType::Bool: {
        isValidArgument = HandleNullableOptional<bool>(arg, argValue, [&](auto * value) {
            // Start with checking for actual boolean values.
            if (strcasecmp(argValue, "true") == 0)
            {
                *value = true;
                return true;
            }

            if (strcasecmp(argValue, "false") == 0)
            {
                *value = false;
                return true;
            }

            // For backwards compat, keep accepting 0 and 1 for now as synonyms
            // for false and true.  Since we set our min to 0 and max to 1 for
            // booleans, calling uint8Handler does the right thing in terms of
            // only allowing those two values.
            uint8_t temp = 0;
            if (!uint8Handler(&temp))
            {
                return false;
            }
            *value = (temp == 1);
            return true;
        });
        break;
    }

    case ArgumentType::Number_uint8: {
        isValidArgument = HandleNullableOptional<uint8_t>(arg, argValue, uint8Handler);
        break;
    }

    case ArgumentType::Number_uint16: {
        isValidArgument = HandleNullableOptional<uint16_t>(arg, argValue, [&](auto * value) {
            std::stringstream ss;
            isHexNotation ? ss << std::hex << argValue : ss << argValue;
            ss >> *value;

            uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
            uint64_t max = arg.max;
            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
        });
        break;
    }

    case ArgumentType::Number_uint32: {
        isValidArgument = HandleNullableOptional<uint32_t>(arg, argValue, [&](auto * value) {
            std::stringstream ss;
            isHexNotation ? ss << std::hex << argValue : ss << argValue;
            ss >> *value;

            uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
            uint64_t max = arg.max;
            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
        });
        break;
    }

    case ArgumentType::Number_uint64: {
        isValidArgument = HandleNullableOptional<uint64_t>(arg, argValue, [&](auto * value) {
            std::stringstream ss;
            isHexNotation ? ss << std::hex << argValue : ss << argValue;
            ss >> *value;

            uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
            uint64_t max = arg.max;
            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
        });
        break;
    }

    case ArgumentType::Number_int8: {
        isValidArgument = HandleNullableOptional<int8_t>(arg, argValue, [&](auto * value) {
            // stringstream treats int8_t as char, which is not what we want here.
            int16_t tmpValue;
            std::stringstream ss;
            isHexNotation ? ss << std::hex << argValue : ss << argValue;
            ss >> tmpValue;
            if (chip::CanCastTo<int8_t>(tmpValue))
            {
                *value = static_cast<int8_t>(tmpValue);

                int64_t min = arg.min;
                int64_t max = chip::CanCastTo<int64_t>(arg.max) ? static_cast<int64_t>(arg.max) : INT64_MAX;
                return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
            }

            return false;
        });
        break;
    }

    case ArgumentType::Number_int16: {
        isValidArgument = HandleNullableOptional<int16_t>(arg, argValue, [&](auto * value) {
            std::stringstream ss;
            isHexNotation ? ss << std::hex << argValue : ss << argValue;
            ss >> *value;

            int64_t min = arg.min;
            int64_t max = chip::CanCastTo<int64_t>(arg.max) ? static_cast<int64_t>(arg.max) : INT64_MAX;
            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
        });
        break;
    }

    case ArgumentType::Number_int32: {
        isValidArgument = HandleNullableOptional<int32_t>(arg, argValue, [&](auto * value) {
            std::stringstream ss;
            isHexNotation ? ss << std::hex << argValue : ss << argValue;
            ss >> *value;

            int64_t min = arg.min;
            int64_t max = chip::CanCastTo<int64_t>(arg.max) ? static_cast<int64_t>(arg.max) : INT64_MAX;
            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
        });
        break;
    }

    case ArgumentType::Number_int64: {
        isValidArgument = HandleNullableOptional<int64_t>(arg, argValue, [&](auto * value) {
            std::stringstream ss;
            isHexNotation ? ss << std::hex << argValue : ss << argValue;
            ss >> *value;

            int64_t min = arg.min;
            int64_t max = chip::CanCastTo<int64_t>(arg.max) ? static_cast<int64_t>(arg.max) : INT64_MAX;
            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
        });
        break;
    }

    case ArgumentType::Float: {
        isValidArgument = HandleNullableOptional<float>(arg, argValue, [&](auto * value) {
            if (strcmp(argValue, "Infinity") == 0)
            {
                *value = INFINITY;
                return true;
            }

            if (strcmp(argValue, "-Infinity") == 0)
            {
                *value = -INFINITY;
                return true;
            }

            std::stringstream ss;
            ss << argValue;
            ss >> *value;
            return (!ss.fail() && ss.eof());
        });
        break;
    }

    case ArgumentType::Double: {
        isValidArgument = HandleNullableOptional<double>(arg, argValue, [&](auto * value) {
            if (strcmp(argValue, "Infinity") == 0)
            {
                *value = INFINITY;
                return true;
            }

            if (strcmp(argValue, "-Infinity") == 0)
            {
                *value = -INFINITY;
                return true;
            }

            std::stringstream ss;
            ss << argValue;
            ss >> *value;
            return (!ss.fail() && ss.eof());
        });
        break;
    }

    case ArgumentType::Address: {
        isValidArgument = HandleNullableOptional<AddressWithInterface>(
            arg, argValue, [&](auto * value) { return ParseAddressWithInterface(argValue, value); });
        break;
    }
    }

    if (!isValidArgument)
    {
        ChipLogError(chipTool, "InitArgs: Invalid argument %s: %s", arg.name, argValue);
    }

    return isValidArgument;
}

void Command::AddArgument(const char * name, const char * value, const char * desc)
{
    ReadOnlyGlobalCommandArgument arg;
    arg.name  = name;
    arg.value = value;
    arg.desc  = desc;

    mReadOnlyGlobalCommandArgument.SetValue(arg);
}

size_t Command::AddArgument(const char * name, char ** value, const char * desc, uint8_t flags)
{
    Argument arg;
    arg.type  = ArgumentType::String;
    arg.name  = name;
    arg.value = reinterpret_cast<void *>(value);
    arg.flags = flags;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, chip::CharSpan * value, const char * desc, uint8_t flags)
{
    Argument arg;
    arg.type  = ArgumentType::CharString;
    arg.name  = name;
    arg.value = reinterpret_cast<void *>(value);
    arg.flags = flags;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, chip::ByteSpan * value, const char * desc, uint8_t flags)
{
    Argument arg;
    arg.type  = ArgumentType::OctetString;
    arg.name  = name;
    arg.value = reinterpret_cast<void *>(value);
    arg.flags = flags;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, AddressWithInterface * out, const char * desc, uint8_t flags)
{
    Argument arg;
    arg.type  = ArgumentType::Address;
    arg.name  = name;
    arg.value = reinterpret_cast<void *>(out);
    arg.flags = flags;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint16_t> * value, const char * desc)
{
    Argument arg;
    arg.type  = ArgumentType::Vector16;
    arg.name  = name;
    arg.value = static_cast<void *>(value);
    arg.min   = min;
    arg.max   = max;
    arg.flags = 0;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint32_t> * value, const char * desc)
{
    Argument arg;
    arg.type  = ArgumentType::Vector32;
    arg.name  = name;
    arg.value = static_cast<void *>(value);
    arg.min   = min;
    arg.max   = max;
    arg.flags = 0;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<uint32_t>> * value,
                            const char * desc)
{
    Argument arg;
    arg.type  = ArgumentType::Vector32;
    arg.name  = name;
    arg.value = static_cast<void *>(value);
    arg.min   = min;
    arg.max   = max;
    arg.flags = Argument::kOptional;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<bool>> * value,
                            const char * desc)
{
    Argument arg;
    arg.type  = ArgumentType::VectorBool;
    arg.name  = name;
    arg.value = static_cast<void *>(value);
    arg.min   = min;
    arg.max   = max;
    arg.flags = Argument::kOptional;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, ComplexArgument * value, const char * desc, uint8_t flags)
{
    Argument arg;
    arg.type  = ArgumentType::Complex;
    arg.name  = name;
    arg.value = static_cast<void *>(value);
    arg.flags = flags;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, CustomArgument * value, const char * desc)
{
    Argument arg;
    arg.type  = ArgumentType::Custom;
    arg.name  = name;
    arg.value = const_cast<void *>(reinterpret_cast<const void *>(value));
    arg.flags = 0;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, std::vector<CustomArgument *> * value, const char * desc)
{
    Argument arg;
    arg.type  = ArgumentType::VectorCustom;
    arg.name  = name;
    arg.value = static_cast<void *>(value);
    arg.flags = 0;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, float min, float max, float * out, const char * desc, uint8_t flags)
{
    Argument arg;
    arg.type  = ArgumentType::Float;
    arg.name  = name;
    arg.value = reinterpret_cast<void *>(out);
    arg.flags = flags;
    arg.desc  = desc;
    // Ignore min/max for now; they're always +-Infinity anyway.

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, double min, double max, double * out, const char * desc, uint8_t flags)
{
    Argument arg;
    arg.type  = ArgumentType::Double;
    arg.name  = name;
    arg.value = reinterpret_cast<void *>(out);
    arg.flags = flags;
    arg.desc  = desc;
    // Ignore min/max for now; they're always +-Infinity anyway.

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, const char * desc,
                            uint8_t flags)
{
    Argument arg;
    arg.type  = type;
    arg.name  = name;
    arg.value = out;
    arg.min   = min;
    arg.max   = max;
    arg.flags = flags;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, const char * desc, uint8_t flags)
{
    Argument arg;
    arg.type  = ArgumentType::Number_uint8;
    arg.name  = name;
    arg.value = out;
    arg.min   = min;
    arg.max   = max;
    arg.flags = flags;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, std::vector<std::string> * value, const char * desc)
{
    Argument arg;
    arg.type  = ArgumentType::VectorString;
    arg.name  = name;
    arg.value = static_cast<void *>(value);
    arg.flags = 0;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, chip::Optional<std::vector<std::string>> * value, const char * desc)
{
    Argument arg;
    arg.type  = ArgumentType::VectorString;
    arg.name  = name;
    arg.value = static_cast<void *>(value);
    arg.flags = Argument::kOptional;
    arg.desc  = desc;

    return AddArgumentToList(std::move(arg));
}

const char * Command::GetArgumentName(size_t index) const
{
    if (index < mArgs.size())
    {
        return mArgs.at(index).name;
    }

    return nullptr;
}

const char * Command::GetArgumentDescription(size_t index) const
{
    if (index < mArgs.size())
    {
        return mArgs.at(index).desc;
    }

    return nullptr;
}

const char * Command::GetReadOnlyGlobalCommandArgument() const
{
    if (GetAttribute())
    {
        return GetAttribute();
    }

    if (GetEvent())
    {
        return GetEvent();
    }

    return nullptr;
}

const char * Command::GetAttribute() const
{
    if (mReadOnlyGlobalCommandArgument.HasValue())
    {
        return mReadOnlyGlobalCommandArgument.Value().value;
    }

    return nullptr;
}

const char * Command::GetEvent() const
{
    if (mReadOnlyGlobalCommandArgument.HasValue())
    {
        return mReadOnlyGlobalCommandArgument.Value().value;
    }

    return nullptr;
}

size_t Command::AddArgumentToList(Argument && argument)
{
    if (argument.isOptional() || mArgs.empty() || !mArgs.back().isOptional())
    {
        // Safe to just append.
        mArgs.emplace_back(std::move(argument));
        return mArgs.size();
    }

    // We're inserting a non-optional arg but we already have something optional
    // in the list.  Insert before the first optional arg.
    for (auto cur = mArgs.cbegin(), end = mArgs.cend(); cur != end; ++cur)
    {
        if ((*cur).isOptional())
        {
            mArgs.emplace(cur, std::move(argument));
            return mArgs.size();
        }
    }

    // Never reached.
    VerifyOrDie(false);
    return 0;
}

namespace {
template <typename T>
void ResetOptionalArg(const Argument & arg)
{
    VerifyOrDie(arg.isOptional());

    if (arg.isNullable())
    {
        reinterpret_cast<chip::Optional<chip::app::DataModel::Nullable<T>> *>(arg.value)->ClearValue();
    }
    else
    {
        reinterpret_cast<chip::Optional<T> *>(arg.value)->ClearValue();
    }
}
} // anonymous namespace

void Command::ResetArguments()
{
    for (const auto & arg : mArgs)
    {
        const ArgumentType type = arg.type;
        if (arg.isOptional())
        {
            // Must always clean these up so they don't carry over to the next
            // command invocation in interactive mode.
            switch (type)
            {
            case ArgumentType::Complex: {
                // Optional Complex arguments are not currently supported via the <chip::Optional> class.
                // Instead, they must be explicitly specified as optional using the kOptional flag,
                // and the base TypedComplexArgument<T> class is referenced.
                auto argument = static_cast<ComplexArgument *>(arg.value);
                argument->Reset();
                break;
            }
            case ArgumentType::Custom: {
                // No optional custom arguments so far.
                VerifyOrDie(false);
                break;
            }
            case ArgumentType::VectorString: {
                ResetOptionalArg<std::vector<std::string>>(arg);
                break;
            }
            case ArgumentType::VectorBool: {
                ResetOptionalArg<std::vector<bool>>(arg);
                break;
            }
            case ArgumentType::Vector16: {
                // No optional Vector16 arguments so far.
                VerifyOrDie(false);
                break;
            }
            case ArgumentType::Vector32: {
                ResetOptionalArg<std::vector<uint32_t>>(arg);
                break;
            }
            case ArgumentType::VectorCustom: {
                // No optional VectorCustom arguments so far.
                VerifyOrDie(false);
                break;
            }
            case ArgumentType::String: {
                ResetOptionalArg<char *>(arg);
                break;
            }
            case ArgumentType::CharString: {
                ResetOptionalArg<chip::CharSpan>(arg);
                break;
            }
            case ArgumentType::OctetString: {
                ResetOptionalArg<chip::ByteSpan>(arg);
                break;
            }
            case ArgumentType::Bool: {
                ResetOptionalArg<bool>(arg);
                break;
            }
            case ArgumentType::Number_uint8: {
                ResetOptionalArg<uint8_t>(arg);
                break;
            }
            case ArgumentType::Number_uint16: {
                ResetOptionalArg<uint16_t>(arg);
                break;
            }
            case ArgumentType::Number_uint32: {
                ResetOptionalArg<uint32_t>(arg);
                break;
            }
            case ArgumentType::Number_uint64: {
                ResetOptionalArg<uint64_t>(arg);
                break;
            }
            case ArgumentType::Number_int8: {
                ResetOptionalArg<int8_t>(arg);
                break;
            }
            case ArgumentType::Number_int16: {
                ResetOptionalArg<int16_t>(arg);
                break;
            }
            case ArgumentType::Number_int32: {
                ResetOptionalArg<int32_t>(arg);
                break;
            }
            case ArgumentType::Number_int64: {
                ResetOptionalArg<int64_t>(arg);
                break;
            }
            case ArgumentType::Float: {
                ResetOptionalArg<float>(arg);
                break;
            }
            case ArgumentType::Double: {
                ResetOptionalArg<double>(arg);
                break;
            }
            case ArgumentType::Address: {
                ResetOptionalArg<AddressWithInterface>(arg);
                break;
            }
            }
        }
        else
        {
            // Some non-optional arguments have state that needs to be cleaned
            // up too.
            if (type == ArgumentType::Vector16)
            {
                auto vectorArgument = static_cast<std::vector<uint16_t> *>(arg.value);
                vectorArgument->clear();
            }
            else if (type == ArgumentType::Vector32)
            {
                auto vectorArgument = static_cast<std::vector<uint32_t> *>(arg.value);
                vectorArgument->clear();
            }
            else if (type == ArgumentType::VectorCustom)
            {
                auto vectorArgument = static_cast<std::vector<CustomArgument *> *>(arg.value);
                for (auto & customArgument : *vectorArgument)
                {
                    delete customArgument;
                }
                vectorArgument->clear();
            }
            else if (type == ArgumentType::Complex)
            {
                auto argument = static_cast<ComplexArgument *>(arg.value);
                argument->Reset();
            }
        }
    }
}
