/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 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
 *      Support functions for parsing command-line arguments.
 *
 */

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

#include "CHIPArgParser.hpp"

#if CHIP_CONFIG_ENABLE_ARG_PARSER

#include <climits>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
#include <lib/support/SafeInt.h>
#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>

/*
 * TODO: Revisit these if and when fabric ID and node ID support has
 *       been integrated into the stack.
 */
#ifndef CHIP_ARG_PARSER_PARSE_FABRIC_ID
#define CHIP_ARG_PARSER_PARSE_FABRIC_ID 0
#endif // CHIP_ARG_PARSER_PARSE_FABRIC_ID

namespace chip {
namespace ArgParser {

using namespace chip;

static char * MakeShortOptions(OptionSet ** optSets);
static struct option * MakeLongOptions(OptionSet ** optSets);
static int32_t SplitArgs(char * argStr, char **& argList, char * initialArg = nullptr);
static bool GetNextArg(char *& parsePoint);
static size_t CountOptionSets(OptionSet * optSets[]);
static size_t CountAllOptions(OptionSet * optSets[]);
static void FindOptionByIndex(OptionSet ** optSets, int optIndex, OptionSet *& optSet, OptionDef *& optDef);
static void FindOptionById(OptionSet ** optSets, int optId, OptionSet *& optSet, OptionDef *& optDef);
static const char ** MakeUniqueHelpGroupNamesList(OptionSet * optSets[]);
static void PutStringWithNewLine(FILE * s, const char * str);
static void PutStringWithBlankLine(FILE * s, const char * str);
#if CHIP_CONFIG_ENABLE_ARG_PARSER_VALIDITY_CHECKS
static bool SanityCheckOptions(OptionSet * optSets[]);
#endif // CHIP_CONFIG_ENABLE_ARG_PARSER_VALIDITY_CHECKS

static inline bool IsShortOptionChar(int ch)
{
    return isgraph(ch);
}

/**
 * @brief
 * The list of OptionSets passed to the currently active ParseArgs() call.
 *
 * @details
 * This value will be NULL when no call to ParseArgs() is in progress.
 */
OptionSet ** gActiveOptionSets = nullptr;

/**
 * @brief
 * Pointer to function used to print errors that occur during argument parsing.
 *
 * @details
 * Applications should call PrintArgError() to report errors in their option and
 * non-option argument handling functions, rather than printing directly to
 * stdout/stderr.
 *
 * Defaults to a pointer to the `DefaultPrintArgError()` function.
 */
void (*PrintArgError)(const char * msg, ...) = DefaultPrintArgError;

/**
 * @fn bool ParseArgs(const char *progName, int argc, char * const argv[], OptionSet *optSets[],
 * NonOptionArgHandlerFunct nonOptArgHandler, bool ignoreUnknown)
 *
 * @brief
 * Parse a set of command line-style arguments, calling handling functions to process each
 * option and non-option argument.
 *
 * @param[in]  progName             The name of the program or context in which the arguments are
 *                                  being parsed.  This string will be used to prefix error
 *                                  messages and warnings.
 * @param[in]  argc                 The number of arguments to be parsed, plus 1.
 * @param[in]  argv                 An array of argument strings to be parsed.  The array length must
 *                                  be 1 greater than the value specified for argc, and
 *                                  argv[argc] must be set to NULL.  Argument parsing begins with the
 *                                  *second* array element (argv[1]); element 0 is ignored.
 * @param[in]  optSets              A list of pointers to `OptionSet` structures that define the legal
 *                                  options.  The supplied list must be terminated with a NULL.
 * @param[in]  nonOptArgHandler     A pointer to a function that will be called once option parsing
 *                                  is complete with any remaining non-option arguments .  The function
 *                                  is called regardless of whether any arguments remain.  If a NULL
 *                                  is passed `ParseArgs()` will report an error if any non-option
 *                                  arguments are present.
 * @param[in]  ignoreUnknown        If true, silently ignore any unrecognized options.
 *
 * @return                          `true` if all options and non-option arguments were parsed
 *                                  successfully; `false` if an option was unrecognized or if one of
 *                                  the handler functions failed (i.e. returned false).
 *
 *
 * @details
 * ParseArgs() takes a list of arguments (`argv`) and parses them according to a set of supplied
 * option definitions.  The function supports both long (--opt) and short (-o) options and implements
 * the same option syntax as the GNU getopt_long(3) function.
 *
 * Option definitions are passed to ParseArgs() as an array of OptionSet structures (`optSets`).
 * Each OptionSet contains an array of option definitions and a handler function. ParseArgs()
 * processes option arguments in the given order, calling the respective handler function for
 * each recognized option.  Once all options have been parsed, a separate non-option handler
 * function (`nonOptArgHandler`) is called once to process any remaining arguments.
 *
 *
 * ## OPTION SETS
 *
 * An OptionSet contains a set of option definitions along with a pointer to a handler function
 * that will be called when one of the associated options is encountered.  Option sets also
 * contain help text describing the syntax and purpose of each option (see OPTION HELP below).
 * Option sets are designed to allow the creation of re-usable collections of related options.
 * This simplifies the effort needed to maintain multiple applications that accept similar options
 * (e.g. test applications).
 *
 * There are two patterns for defining OptionSets--one can either initialize an instance of the
 * OptionSet struct itself, e.g. as a static global, or subclass OptionSetBase and provide a
 * constructor.  The latter uses a pure virtual `HandleOption()` function to delegate option
 * handling to the subclass.
 *
 * Lists of OptionSets are passed to the ParseArgs() function as a NULL-terminated array of pointers.
 * E.g.:
 *
 *     static OptionSet gToolOptions =
 *     {
 *         HandleOption,        // handler function
 *         gToolOptionDefs,  // array of option definitions
 *         "GENERAL OPTIONS",   // help group
 *         gToolOptionHelp   // option help text
 *     };
 *
 *     static OptionSet *gOptionSets[] =
 *     {
 *         &gToolOptions,
 *         &gNetworkOptions,
 *         &gTestingOptions,
 *         &gHelpOptions,
 *         NULL
 *     };
 *
 *     int main(int argc, char *argv[])
 *     {
 *         if (!ParseArgs("test-app", argc, argv, gOptionSets))
 *         {
 *             ...
 *         }
 *     }
 *
 *
 * ## OPTION DEFINITIONS
 *
 * Options are defined using the `OptionDef` structure. Option definitions are organized as an array
 * of OptionDef elements, where each element contains: the name of the option, a integer id that is
 * used to identify the option, and whether the option expects/allows an argument.  The end of the
 * option array is signaled by a NULL Name field.  E.g.:
 *
 *     enum
 *     {
 *         kOpt_Listen = 1000,
 *         kOpt_Length,
 *         kOpt_Count,
 *     };
 *
 *     static OptionDef gToolOptionDefs[] =
 *     {
 *         // NAME         REQUIRES/ALLOWS ARG?  ID/SHORT OPTION CHAR
 *         // ============================================================
 *         {  "listen",    kNoArgument,          kOpt_Listen     },
 *         {  "length",    kArgumentRequired,    kOpt_Length     },
 *         {  "count",     kArgumentRequired,    kOpt_Count      },
 *         {  "num",       kArgumentRequired,    kOpt_Count      }, // alias for --count
 *         {  "debug",     kArgumentOptional,    'd'             },
 *         {  "help",      kNoArgument,          'h'             },
 *         {  NULL }
 *     };
 *
 *
 * ## OPTION IDS
 *
 * Option ids identify options to the code that handles them (the OptionHandler function). Option ids
 * are relative to the OptionSet in which they appear, and thus may be reused across different
 * OptionSets (however see SHORT OPTIONS below).  Common convention is to start numbering option ids
 * at 1000, however any number > 128 can be used.  Alias options can be created by using the same
 * option id with different option names.
 *
 *
 * ## SHORT OPTIONS
 *
 * Unlike getopt_long(3), ParseArgs() does not take a separate string specifying the list of short
 * option characters.  Rather, any option whose id value falls in the range of graphical ASCII
 * characters will allow that character to be used as a short option.
 *
 * ParseArgs() requires that short option characters be unique across *all* OptionSets.  Because of
 * this, the use of short options is discouraged for any  OptionSets that are shared across programs
 * due to the significant chance for collisions.  Short options characters may be reused within a
 * single OptionSet to allow for the creation of alias long option names.
 *
 *
 * ## OPTION HELP
 *
 * Each OptionSet contains an `OptionHelp` string that describes the purpose and syntax of the
 * associated options.  These strings are used by the `PrintOptionHelp()` function to generate
 * option usage information.
 *
 * By convention, option help strings consist of a syntax example following by a textual
 * description of the option.  If the option has a short version, or an alias name, it is given
 * before primary long name.  For consistency, syntax lines are indented with 2 spaces, while
 * description lines are indented with 7 spaces.  A single blank line follows each option
 * description, including the last one.
 *
 * E.g.:
 *
 *     static const char *const gToolOptionHelp =
 *         "  --listen\n"
 *         "       Listen and respond to requests sent from another node.\n"
 *         "\n"
 *         "  --length <num>\n"
 *         "       Send requests with the specified number of bytes in the payload.\n"
 *         "\n"
 *         "  --num, --count <num>\n"
 *         "       Send the specified number of requests and exit.\n"
 *         "\n"
 *         "  -d, --debug [<level>]\n"
 *         "       Set debug logging to the given level. (Default: 1)\n"
 *         "\n"
 *         "  -h, --help\n"
 *         "       Print help information.\n"
 *         "\n";
 *
 *
 * ## OPTION HELP GROUPS
 *
 * OptionSets contain a `HelpGroupName` string which is used to group options together in the
 * help output.  The `PrintOptionHelp()` function uses the HelpGroupName as a section title in
 * the generated usage output.  If multiple OptionSets have the same HelpGroupName,
 * PrintOptionHelp() will print the option help for the different OptionSets together under
 * a common section title.
 *
 */
bool ParseArgs(const char * progName, int argc, char * const argv[], OptionSet * optSets[],
               NonOptionArgHandlerFunct nonOptArgHandler, bool ignoreUnknown)
{
    bool res = false;
    char optName[64];
    char * optArg;
    char * shortOpts         = nullptr;
    struct option * longOpts = nullptr;
    OptionSet * curOptSet;
    OptionDef * curOpt;
    bool handlerRes;
#if CHIP_CONFIG_NON_POSIX_LONG_OPT
    int lastOptIndex    = 0;
    int subOptIndex     = 0;
    int currentOptIndex = 0;
#endif // CHIP_CONFIG_NON_POSIX_LONG_OPT

    // The getopt() functions do not support recursion, so exit immediately with an
    // error if called recursively.
    if (gActiveOptionSets != nullptr)
    {
        PrintArgError("INTERNAL ERROR: ParseArgs() called recursively\n", progName);
        return false;
    }

    // The C standard mandates that argv[argc] == NULL and certain versions of getopt() require this
    // to function properly.  So fail if this is not true.
    if (argv[argc] != nullptr)
    {
        PrintArgError("INTERNAL ERROR: argv[argc] != NULL\n", progName);
        return false;
    }

    // Set gActiveOptionSets to the current option set list.
    gActiveOptionSets = optSets;

#if CHIP_CONFIG_ENABLE_ARG_PARSER_VALIDITY_CHECKS
    if (!SanityCheckOptions(optSets))
        goto done;
#endif

    // Generate a short options string in the format expected by getopt_long().
    shortOpts = MakeShortOptions(optSets);
    if (shortOpts == nullptr)
    {
        PrintArgError("%s: Memory allocation failure\n", progName);
        goto done;
    }

    // Generate a list of long option structures in the format expected by getopt_long().
    longOpts = MakeLongOptions(optSets);
    if (longOpts == nullptr)
    {
        PrintArgError("%s: Memory allocation failure\n", progName);
        goto done;
    }

    // Force getopt() to reset its internal state.
    optind = 0;

    // Process any option arguments...
    while (true)
    {
        int id;
        int optIndex = -1;

        // Attempt to match the current option argument (argv[optind]) against the defined long and short options.
        optarg = nullptr;
        optopt = 0;
#if CHIP_CONFIG_NON_POSIX_LONG_OPT
        // to check if index has changed
        lastOptIndex = currentOptIndex;
        // optind will not increment on error, this is why we need to keep track of the current option
        // this is for use when getopt_long fails to find the option and we need to print the error
        currentOptIndex = optind;
        // if it's the first run, optind is not set and we need to find the first option ourselves
        if (!currentOptIndex)
        {
            while (currentOptIndex < argc)
            {
                currentOptIndex++;
                if (*argv[currentOptIndex] == '-')
                {
                    break;
                }
            }
        }
        // similarly we need to keep track of short opts index for groups like "-fba"
        // if the index has not changed that means we are still analysing the same group
        if (lastOptIndex != currentOptIndex)
        {
            subOptIndex = 0;
        }
        else
        {
            subOptIndex++;
        }
#endif // CHIP_CONFIG_NON_POSIX_LONG_OPT
        id = getopt_long(argc, argv, shortOpts, longOpts, &optIndex);

        // Stop if there are no more options.
        if (id == -1)
            break;

        // If the current option is unrecognized, fail with an error message unless ignoreUnknown == true.
        if (id == '?')
        {
            if (ignoreUnknown)
                continue;
#if CHIP_CONFIG_NON_POSIX_LONG_OPT
            // getopt_long doesn't tell us if the option which failed to match is long or short so check
            bool isLongOption = false;
            if (strlen(argv[currentOptIndex]) > 2 && argv[currentOptIndex][1] == '-')
            {
                isLongOption = true;
            }
            if (optopt == 0 || isLongOption)
            {
                // getopt_long function incorrectly treats unknown long option as short opt group
                if (subOptIndex == 0)
                {
                    PrintArgError("%s: Unknown option: %s\n", progName, argv[currentOptIndex]);
                }
            }
            else if (optopt == '?')
            {
                PrintArgError("%s: Unknown option: -%c\n", progName, argv[currentOptIndex][subOptIndex + 1]);
            }
            else
            {
                PrintArgError("%s: Unknown option: -%c\n", progName, optopt);
            }
#else
            if (optopt != 0)
                PrintArgError("%s: Unknown option: -%c\n", progName, optopt);
            else
                PrintArgError("%s: Unknown option: %s\n", progName, argv[optind - 1]);
#endif // CHIP_CONFIG_NON_POSIX_LONG_OPT
            goto done;
        }

        // If the option was recognized, but it is lacking an argument, fail with
        // an error message.
        if (id == ':')
        {
            // NOTE: with the way getopt_long() works, it is impossible to tell whether the option that
            // was missing an argument was a long option or a short option.
#if CHIP_CONFIG_NON_POSIX_LONG_OPT
            PrintArgError("%s: Missing argument for %s option\n", progName, argv[currentOptIndex]);
#else
            PrintArgError("%s: Missing argument for %s option\n", progName, argv[optind - 1]);
#endif // CHIP_CONFIG_NON_POSIX_LONG_OPT
            goto done;
        }

        // If a long option was matched...
        if (optIndex != -1)
        {

            // Locate the option set and definition using the index value returned by getopt_long().
            FindOptionByIndex(optSets, optIndex, curOptSet, curOpt);

            // Form a string containing the name of the option as it appears on the command line.
            snprintf(optName, sizeof(optName), "--%s", curOpt->Name);
        }

        // Otherwise a short option was matched...
        else
        {
            // Locate the option set and definition using the option id.
            FindOptionById(optSets, id, curOptSet, curOpt);

            // Form a string containing the name of the short option as it would appears on the
            // command line if given by itself.
            snprintf(optName, sizeof(optName), "-%c", id);
        }

        // Prevent handlers from inadvertently using the getopt global optarg.
        optArg = optarg;
        optarg = nullptr;

        // Call the option handler function defined for the matching option set.
        // Exit immediately if the option handler failed.
        handlerRes = curOptSet->OptionHandler(progName, curOptSet, id, optName, optArg);
        if (!handlerRes)
            goto done;
    }

    // If supplied, call the non-option argument handler with the remaining arguments (if any).
    if (nonOptArgHandler != nullptr)
    {
        if (!nonOptArgHandler(progName, argc - optind, argv + optind))
            goto done;
    }

    // otherwise, if there are additional arguments, fail with an error.
    else if (optind < argc)
    {
        PrintArgError("%s: Unexpected argument: %s\n", progName, argv[optind]);
        goto done;
    }

    res = true;

done:

    if (shortOpts != nullptr)
        chip::Platform::MemoryFree(shortOpts);
    if (longOpts != nullptr)
        chip::Platform::MemoryFree(longOpts);

    gActiveOptionSets = nullptr;

    return res;
}

bool ParseArgs(const char * progName, int argc, char * const argv[], OptionSet * optSets[],
               NonOptionArgHandlerFunct nonOptArgHandler)
{
    return ParseArgs(progName, argc, argv, optSets, nonOptArgHandler, false);
}

bool ParseArgs(const char * progName, int argc, char * const argv[], OptionSet * optSets[])
{
    return ParseArgs(progName, argc, argv, optSets, nullptr, false);
}

/**
 * @brief
 * Parse a set of arguments from a given string.
 *
 * @param[in]  progName             The name of the program or context in which the arguments are
 *                                  being parsed.  This string will be used to prefix error
 *                                  messages and warnings.
 * @param[in]  argStr               A string containing options and arguments to be parsed.
 * @param[in]  optSets              A list of pointers to `OptionSet` structures that define the legal
 *                                  options.  The supplied list must be terminated with a NULL.
 * @param[in]  nonOptArgHandler     A pointer to a function that will be called once option parsing
 *                                  is complete with any remaining non-option arguments .  The function
 *                                  is called regardless of whether any arguments remain.  If a NULL
 *                                  is passed `ParseArgs()` will report an error if any non-option
 *                                  arguments are present.
 * @param[in]  ignoreUnknown        If true, silently ignore any unrecognized options.
 *
 * @return                          `true` if all options and non-option arguments were parsed
 *                                  successfully; `false` if an option was unrecognized, if one of
 *                                  the handler functions failed (i.e. returned false) or if an
 *                                  internal error occurred.
 *
 * @details
 * ParseArgsFromString() splits a given string (`argStr`) into a set of arguments and parses the
 * arguments using the ParseArgs() function.
 *
 * The syntax of the input strings is similar to unix shell command syntax, but with a simplified
 * quoting scheme.  Specifically:
 *
 * - Arguments are delimited by whitespace, unless the whitespace is quoted or escaped.
 *
 * - A backslash escapes the following character, causing it to be treated as a normal character.
 * The backslash itself is stripped.
 *
 * - Single or double quotes begin/end quoted substrings.  Within a substring, the only special
 * characters are backslash, which escapes the next character, and the corresponding end quote.
 * The begin/end quote characters are stripped.
 *
 * E.g.:
 *
 *     --listen --count 10 --sw-version '1.0 (DEVELOPMENT)' "--hostname=nest.com"
 *
 */
bool ParseArgsFromString(const char * progName, const char * argStr, OptionSet * optSets[],
                         NonOptionArgHandlerFunct nonOptArgHandler, bool ignoreUnknown)
{
    char ** argv = nullptr;
    int argc;
    bool res;

    chip::Platform::ScopedMemoryString argStrCopy(argStr, strlen(argStr));
    if (!argStrCopy)
    {
        PrintArgError("%s: Memory allocation failure\n", progName);
        return false;
    }

    argc = SplitArgs(argStrCopy.Get(), argv, const_cast<char *>(progName));
    if (argc < 0)
    {
        PrintArgError("%s: Memory allocation failure\n", progName);
        return false;
    }

    res = ParseArgs(progName, argc, argv, optSets, nonOptArgHandler, ignoreUnknown);

    chip::Platform::MemoryFree(argv);

    return res;
}

bool ParseArgsFromString(const char * progName, const char * argStr, OptionSet * optSets[],
                         NonOptionArgHandlerFunct nonOptArgHandler)
{
    return ParseArgsFromString(progName, argStr, optSets, nonOptArgHandler, false);
}

bool ParseArgsFromString(const char * progName, const char * argStr, OptionSet * optSets[])
{
    return ParseArgsFromString(progName, argStr, optSets, nullptr, false);
}

/**
 * @brief
 * Parse a set of arguments from a named environment variable
 *
 * @param[in]  progName             The name of the program or context in which the arguments are
 *                                  being parsed.  This string will be used to prefix error
 *                                  messages and warnings.
 * @param[in]  varName              The name of the environment variable.
 * @param[in]  optSets              A list of pointers to `OptionSet` structures that define the legal
 *                                  options.  The supplied list must be terminated with a NULL.
 * @param[in]  nonOptArgHandler     A pointer to a function that will be called once option parsing
 *                                  is complete with any remaining non-option arguments .  The function
 *                                  is called regardless of whether any arguments remain.  If a NULL
 *                                  is passed `ParseArgs()` will report an error if any non-option
 *                                  arguments are present.
 * @param[in]  ignoreUnknown        If true, silently ignore any unrecognized options.
 *
 * @return                          `true` if all options and non-option arguments were parsed
 *                                  successfully, or if the specified environment variable is not set;
 *                                  `false` if an option was unrecognized, if one of the handler
 *                                  functions failed (i.e. returned false) or if an internal error
 *                                  occurred.
 *
 * @details
 * ParseArgsFromEnvVar() reads a named environment variable and passes the value to `ParseArgsFromString()`
 * for parsing.  If the environment variable is not set, the function does nothing.
 */

bool ParseArgsFromEnvVar(const char * progName, const char * varName, OptionSet * optSets[],
                         NonOptionArgHandlerFunct nonOptArgHandler, bool ignoreUnknown)
{
    const char * argStr = getenv(varName);
    if (argStr == nullptr)
        return true;
    return ParseArgsFromString(progName, argStr, optSets, nonOptArgHandler, ignoreUnknown);
}

bool ParseArgsFromEnvVar(const char * progName, const char * varName, OptionSet * optSets[])
{
    return ParseArgsFromEnvVar(progName, varName, optSets, nullptr, false);
}

bool ParseArgsFromEnvVar(const char * progName, const char * varName, OptionSet * optSets[],
                         NonOptionArgHandlerFunct nonOptArgHandler)
{
    return ParseArgsFromEnvVar(progName, varName, optSets, nonOptArgHandler, false);
}

/**
 * @brief
 * Print the help text for a specified list of options to a stream.
 *
 * @param[in]  optSets              A list of pointers to `OptionSet` structures that contain the
 *                                  help text to print.
 * @param[in]  s                    The FILE stream to which the help text should be printed.
 *
 */
void PrintOptionHelp(OptionSet * optSets[], FILE * s)
{
    // Get a list of the unique help group names for the given option sets.
    const char ** helpGroupNames = MakeUniqueHelpGroupNamesList(optSets);
    if (helpGroupNames == nullptr)
    {
        PrintArgError("Memory allocation failure\n");
        return;
    }

    // For each help group...
    for (size_t nameIndex = 0; helpGroupNames[nameIndex] != nullptr; nameIndex++)
    {
        // Print the group name.
        PutStringWithBlankLine(s, helpGroupNames[nameIndex]);

        // Print the option help text for all options that have the same group name.
        for (size_t optSetIndex = 0; optSets[optSetIndex] != nullptr; optSetIndex++)
            if (strcasecmp(helpGroupNames[nameIndex], optSets[optSetIndex]->HelpGroupName) == 0)
            {
                PutStringWithBlankLine(s, optSets[optSetIndex]->OptionHelp);
            }
    }

    chip::Platform::MemoryFree(helpGroupNames);
}

/**
 * @brief
 * Print an error message associated with argument parsing.
 *
 * @param[in]  msg   The message to be printed.
 *
 * @details
 * Default function used to print error messages that arise due to the parsing
 * of arguments.
 *
 * Applications should call through the PrintArgError function pointer, rather
 * than calling this function directly.
 */
void ENFORCE_FORMAT(1, 2) DefaultPrintArgError(const char * msg, ...)
{
    va_list ap;

    va_start(ap, msg);
    vfprintf(stderr, msg, ap);
    va_end(ap);
}

/**
 * Parse a string as a boolean value.
 *
 * This function accepts the following input values (case-insensitive):
 * "true", "yes", "t", "y", "1", "false", "no", "f", "n", "0".
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the value to parse.
 * @param[out] output A reference to storage for a bool to which the parsed
 *                    value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseBoolean(const char * str, bool & output)
{
    if (strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0 ||
        ((str[0] == '1' || str[0] == 't' || str[0] == 'T' || str[0] == 'y' || str[0] == 'Y') && str[1] == 0))
    {
        output = true;
        return true;
    }

    if (strcasecmp(str, "false") == 0 || strcasecmp(str, "no") == 0 ||
        ((str[0] == '0' || str[0] == 'f' || str[0] == 'F' || str[0] == 'n' || str[0] == 'N') && str[1] == 0))
    {
        output = false;
        return true;
    }

    return false;
}

/**
 * Parse and attempt to convert a string to a 64-bit unsigned integer,
 * applying the appropriate interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 64-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 * @param[in]  base   The base according to which the string should be
 *                    interpreted and parsed. If 0 or 16, the string may
 *                    be hexadecimal and prefixed with "0x". Otherwise, a 0
 *                    is implied as 10 unless a leading 0 is encountered in
 *                    which 8 is implied.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, uint64_t & output, int base)
{
    char * parseEnd;

    errno  = 0;
    output = strtoull(str, &parseEnd, base);

    return parseEnd > str && *parseEnd == 0 && (output != ULLONG_MAX || errno == 0);
}

/**
 * Parse and attempt to convert a string to a 32-bit unsigned integer,
 * applying the appropriate interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 32-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 * @param[in]  base   The base according to which the string should be
 *                    interpreted and parsed. If 0 or 16, the string may
 *                    be hexadecimal and prefixed with "0x". Otherwise, a 0
 *                    is implied as 10 unless a leading 0 is encountered in
 *                    which 8 is implied.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, uint32_t & output, int base)
{
    char * parseEnd;
    unsigned long v;

    errno = 0;
    v     = strtoul(str, &parseEnd, base);
    if (!CanCastTo<uint32_t>(v))
    {
        return false;
    }
    output = static_cast<uint32_t>(v);

    return parseEnd > str && *parseEnd == 0 && (v != ULONG_MAX || errno == 0);
}

/**
 * Parse and attempt to convert a string to a 32-bit signed integer,
 * applying the appropriate interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 32-bit signed integer
 *                    to which the parsed value will be stored on success.
 * @param[in]  base   The base according to which the string should be
 *                    interpreted and parsed. If 0 or 16, the string may
 *                    be hexadecimal and prefixed with "0x". Otherwise, a 0
 *                    is implied as 10 unless a leading 0 is encountered in
 *                    which 8 is implied.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, int32_t & output, int base)
{
    char * parseEnd;
    long v;

    errno = 0;
    v     = strtol(str, &parseEnd, base);
    if (!CanCastTo<int32_t>(v))
    {
        return false;
    }
    output = static_cast<int32_t>(v);

    return parseEnd > str && *parseEnd == 0 && ((v != LONG_MIN && v != LONG_MAX) || errno == 0);
}

/**
 * Parse and attempt to convert a string to a 16-bit unsigned integer,
 * applying the appropriate interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 16-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 * @param[in]  base   The base according to which the string should be
 *                    interpreted and parsed. If 0 or 16, the string may
 *                    be hexadecimal and prefixed with "0x". Otherwise, a 0
 *                    is implied as 10 unless a leading 0 is encountered in
 *                    which 8 is implied.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, uint16_t & output, int base)
{
    uint32_t v;

    if (!ParseInt(str, v, base) || !CanCastTo<uint16_t>(v))
    {
        return false;
    }
    output = static_cast<uint16_t>(v);

    return true;
}

/**
 * Parse and attempt to convert a string to a 8-bit unsigned integer,
 * applying the appropriate interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 8-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 * @param[in]  base   The base according to which the string should be
 *                    interpreted and parsed. If 0 or 16, the string may
 *                    be hexadecimal and prefixed with "0x". Otherwise, a 0
 *                    is implied as 10 unless a leading 0 is encountered in
 *                    which 8 is implied.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, uint8_t & output, int base)
{
    uint32_t v;

    if (!ParseInt(str, v, base) || !CanCastTo<uint8_t>(v))
    {
        return false;
    }
    output = static_cast<uint8_t>(v);

    return true;
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 64-bit unsigned integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 64-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, uint64_t & output)
{
    const int base = 10;

    return ParseInt(str, output, base);
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 32-bit unsigned integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 32-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, uint32_t & output)
{
    const int base = 10;

    return ParseInt(str, output, base);
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 32-bit signed integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 32-bit signed integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, int32_t & output)
{
    const int base = 10;

    return ParseInt(str, output, base);
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 16-bit unsigned integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 16-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, uint16_t & output)
{
    const int base    = 10;
    uint32_t output32 = 0;

    if ((ParseInt(str, output32, base)) && (output32 <= USHRT_MAX))
    {
        output = ((1 << 16) - 1) & output32;
        return true;
    }

    return false;
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 16-bit signed integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 16-bit signed integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, int16_t & output)
{
    const int base   = 10;
    int32_t output32 = 0;

    if ((ParseInt(str, output32, base)) && (output32 <= SHRT_MAX && output32 >= SHRT_MIN))
    {
        output = static_cast<int16_t>(output32);
        return true;
    }

    return false;
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 8-bit unsigned integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 8-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char * str, uint8_t & output)
{
    const int base    = 10;
    uint32_t output32 = 0;

    if ((ParseInt(str, output32, base)) && (output32 <= UCHAR_MAX))
    {
        output = ((1 << 8) - 1) & output32;
        return true;
    }

    return false;
}

#if CHIP_ARG_PARSER_PARSE_FABRIC_ID
/**
 * Parse a CHIP fabric id in text form.
 *
 * @param[in]  str              A pointer to a NULL-terminated C string containing
 *                              the fabric id to parse.
 * @param[out] output           A reference to an uint64_t lvalue in which the
 *                              parsed value will be stored on success.
 * @param[in]  allowReserved    If true, allow the parsing of fabric ids in the
 *                              reserved range.
 *
 * @return true if the value was successfully parsed; false if not.
 *
 * @details
 * The ParseFabricId() function accepts a 64-bit fabric id given in hex format,
 * with or without a leading '0x'.
 */
bool ParseFabricId(const char * str, uint64_t & fabricId, bool allowReserved)
{
    char * parseEnd;

    errno    = 0;
    fabricId = strtoull(str, &parseEnd, 16);
    return parseEnd > str && *parseEnd == 0 && (fabricId != ULLONG_MAX || errno == 0) &&
        (allowReserved || fabricId < kReservedFabricIdStart);
}
#endif // CHIP_ARG_PARSER_PARSE_FABRIC_ID

/**
 * Parse and attempt to convert a string to a 16-bit unsigned subnet
 * ID, interpretting the string as hexadecimal.
 *
 * @param[in]     str       A pointer to a NULL-terminated C string
 *                          representing the subnet ID, formatted as a
 *                          hexadecimal, to parse.
 * @param[in,out] subnetId  A reference to storage for a 16-bit unsigned
 *                          integer to which the parsed subnet ID value
 *                          will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseSubnetId(const char * str, uint16_t & subnetId)
{
    char * parseEnd;
    unsigned long temp;
    bool valid;

    // Reset errno per the strtoul manual page.

    errno = 0;

    // Attempt to parse the subnet ID as a hexadecimal number.

    temp = strtoul(str, &parseEnd, 16);

    // Determine if the parse and conversion were valid.

    valid = (parseEnd > str &&                    // Parsed some valid hexadecimal digits
             *parseEnd == 0 &&                    // Encountered no invalid hexadecimal digits
             (temp != ULONG_MAX || errno == 0) && // No overflow (ERANGE) or invalid base (EINVAL) errors
             temp <= USHRT_MAX);                  // Parsed value is valid for the domain (subnet ID)

    if (valid)
    {
        subnetId = static_cast<uint16_t>(temp);
    }

    return valid;
}

/**
 * Parse a string of bytes given in hex form.
 *
 * @param[in]  hexStr           A pointer to the string to parse.
 * @param[in]  strLen           The number of characters in hexStr to parse.
 * @param[in]  outBuf           A pointer to a buffer into which the parse bytes will
 *                              be stored.
 * @param[in]  outBufSize       The size of the buffer pointed at by `outBuf`.
 * @param[out] outDataLen       A reference to an integer that will receive the total
 *                              number of bytes parsed.  In the event outBuf is not
 *                              big enough to hold the given number of bytes, `outDataLen`
 *                              will be set to UINT32_MAX.
 *
 * @return true if the value was successfully parsed; false if the input data is malformed,
 * or if `outBuf` is too small.
 *
 * @details
 * ParseHexString() expects the input to be in the form of pairs of hex digits (upper or lower case).
 * Hex pairs can optionally be separated by any of the following characters: colon, semicolon, comma, period or dash.
 * Additionally, whitespace characters anywhere in the input string are ignored.
 */
bool ParseHexString(const char * hexStr, uint32_t strLen, uint8_t * outBuf, uint32_t outBufSize, uint32_t & outDataLen)
{
    bool isFirstNibble     = true;
    uint8_t firstNibbleVal = 0;
    const char * p         = hexStr;
    uint32_t dataLen       = 0;

    outDataLen = 0;

    for (; strLen > 0; p++, strLen--)
    {
        char c = *p;
        uint8_t nibbleVal;

        if (c == 0)
            break;
        if (c >= '0' && c <= '9')
            nibbleVal = static_cast<uint8_t>(c - '0');
        else if (c >= 'a' && c <= 'f')
            nibbleVal = static_cast<uint8_t>(10 + (c - 'a'));
        else if (c >= 'A' && c <= 'F')
            nibbleVal = static_cast<uint8_t>(10 + (c - 'A'));
        else if (isspace(c))
            continue;
        else if (isFirstNibble && (c == ':' || c == ';' || c == ',' || c == '.' || c == '-'))
            continue;
        else
        {
            outDataLen = static_cast<decltype(strLen)>(p - hexStr);
            return false;
        }

        if (isFirstNibble)
        {
            firstNibbleVal = nibbleVal;
            isFirstNibble  = false;
        }
        else
        {
            if (outBufSize == 0)
            {
                outDataLen = UINT32_MAX;
                return false;
            }

            *outBuf = static_cast<uint8_t>(firstNibbleVal << 4 | nibbleVal);

            outBuf++;
            outBufSize--;
            dataLen++;

            isFirstNibble = true;
        }
    }

    if (!isFirstNibble)
    {
        outDataLen = static_cast<decltype(strLen)>(p - hexStr);
        return false;
    }

    outDataLen = dataLen;

    return true;
}

// ===== HelpOptions Methods =====

HelpOptions::HelpOptions(const char * appName, const char * appUsage, const char * appVersion) :
    HelpOptions(appName, appUsage, appVersion, nullptr)
{}

HelpOptions::HelpOptions(const char * appName, const char * appUsage, const char * appVersion, const char * appDesc)
{
    // clang-format off
    static OptionDef optionDefs[] =
    {
        { "help",      kNoArgument, 'h' },
        { "version",   kNoArgument, 'v' },
        { }
    };
    // clang-format on
    OptionDefs = optionDefs;

    HelpGroupName = "HELP OPTIONS";

    OptionHelp = "  -h, --help\n"
                 "       Print this output and then exit.\n"
                 "\n"
                 "  -v, --version\n"
                 "       Print the version and then exit.\n"
                 "\n";

    AppName    = appName;
    AppUsage   = appUsage;
    AppVersion = appVersion;
    AppDesc    = appDesc;
}

/**
 * Print a short description of the command's usage followed by instructions on how to get more help.
 */
void HelpOptions::PrintBriefUsage(FILE * s) const
{
    PutStringWithNewLine(s, AppUsage);
    fprintf(s, "Try `%s --help' for more information.\n", AppName);
}

/**
 * Print the full usage information, including information on all available options.
 */
void HelpOptions::PrintLongUsage(OptionSet ** optSets, FILE * s) const
{
    PutStringWithBlankLine(s, AppUsage);
    if (AppDesc != nullptr)
    {
        PutStringWithBlankLine(s, AppDesc);
    }
    PrintOptionHelp(optSets, s);
}

void HelpOptions::PrintVersion(FILE * s) const
{
    fprintf(s, "%s ", AppName);
    PutStringWithNewLine(s, (AppVersion != nullptr) ? AppVersion : "(unknown version)");
}

bool HelpOptions::HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    switch (id)
    {
    case 'h':
        PrintLongUsage(gActiveOptionSets, stdout);
        exit(EXIT_SUCCESS);
        break;
    case 'v':
        PrintVersion(stdout);
        exit(EXIT_SUCCESS);
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

// ===== Private/Internal Methods =====

OptionSetBase::OptionSetBase()
{
    OptionHandler = CallHandleFunct;
}

bool OptionSetBase::CallHandleFunct(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    return static_cast<OptionSetBase *>(optSet)->HandleOption(progName, optSet, id, name, arg);
}

static char * MakeShortOptions(OptionSet ** optSets)
{
    size_t i = 0;

    // Count the number of options.
    size_t totalOptions = CountAllOptions(optSets);

    // Allocate a block of memory big enough to hold the maximum possible size short option string.
    // The buffer needs to be big enough to hold up to 3 characters per short option plus an initial
    // ":" and a terminating null.
    size_t arraySize = 2 + (totalOptions * 3);
    char * shortOpts = static_cast<char *>(chip::Platform::MemoryAlloc(arraySize));
    if (shortOpts == nullptr)
        return nullptr;

    // Prefix the string with ':'.  This tells getopt() to signal missing option arguments distinct
    // from unknown options.
    shortOpts[i++] = ':';

    // For each option set...
    for (; *optSets != nullptr; optSets++)
    {
        // For each option in the current option set...
        for (OptionDef * optDef = (*optSets)->OptionDefs; optDef->Name != nullptr; optDef++)
        {
            // If the option id (val) is suitable as a short option character, add it to the short
            // option string. Append ":" if the option requires an argument and "::" if the argument
            // is optional.
            if (IsShortOptionChar(optDef->Id))
            {
                shortOpts[i++] = static_cast<char>(optDef->Id);
                if (optDef->ArgType != kNoArgument)
                    shortOpts[i++] = ':';
                if (optDef->ArgType == kArgumentOptional)
                    shortOpts[i++] = ':';
            }
        }
    }

    // Terminate the short options string.
    shortOpts[i++] = 0;

    return shortOpts;
}

static struct option * MakeLongOptions(OptionSet ** optSets)
{
    size_t totalOptions = CountAllOptions(optSets);

    // Allocate an array to hold the list of long options.
    size_t arraySize         = (sizeof(struct option) * (totalOptions + 1));
    struct option * longOpts = static_cast<struct option *>(chip::Platform::MemoryAlloc(arraySize));
    if (longOpts == nullptr)
        return nullptr;

    // For each option set...
    size_t i = 0;
    for (; *optSets != nullptr; optSets++)
    {
        // Copy the option definitions into the long options array.
        for (OptionDef * optDef = (*optSets)->OptionDefs; optDef->Name != nullptr; optDef++)
        {
            longOpts[i].name    = optDef->Name;
            longOpts[i].has_arg = static_cast<int>(optDef->ArgType);
            longOpts[i].flag    = nullptr;
            longOpts[i].val     = optDef->Id;
            i++;
        }
    }

    // Terminate the long options array.
    longOpts[i].name = nullptr;

    return longOpts;
}

static int32_t SplitArgs(char * argStr, char **& argList, char * initialArg)
{
    enum
    {
        InitialArgListSize = 10
    };
    size_t argListSize = 0;
    int32_t argCount   = 0;

    // Allocate an array to hold pointers to the arguments.
    argList = static_cast<char **>(chip::Platform::MemoryAlloc(sizeof(char *) * InitialArgListSize));
    if (argList == nullptr)
        return -1;
    argListSize = InitialArgListSize;

    // If an initial argument was supplied, make it the first argument in the array.
    if (initialArg != nullptr)
    {
        argList[0] = initialArg;
        argCount   = 1;
    }

    // Parse arguments from the input string until it is exhausted.
    while (true)
    {
        char * nextArg = argStr;

        // Get the argument in the input string.  Note that this modifies the string buffer.
        if (!GetNextArg(argStr))
            break;

        // Grow the arg list array if needed. Note that we reserve one slot at the end of the array
        // for a NULL entry.
        if (argListSize == static_cast<size_t>(argCount + 1))
        {
            argListSize *= 2;
            argList = static_cast<char **>(chip::Platform::MemoryRealloc(argList, argListSize));
            if (argList == nullptr)
                return -1;
        }

        // Append the argument.
        argList[argCount++] = nextArg;
    }

    // Set the last element in the array to NULL, but do not include this in the count of elements.
    // This is mandated by the C standard and some versions of getopt_long() depend on it.
    argList[argCount] = nullptr;

    return argCount;
}

static bool GetNextArg(char *& parsePoint)
{
    char quoteChar = 0;
    char * argEnd  = parsePoint;

    // Skip any leading whitespace.
    while (*parsePoint != 0 && isspace(*parsePoint))
        parsePoint++;

    // Return false if there are no further arguments.
    if (*parsePoint == 0)
        return false;

    // Iterate over characters until we find the end of an argument.
    // As we iterate, we will accumulate the unquoted and unescaped
    // argument characters in the input buffer starting at the initial
    // parsePoint position.
    while (*parsePoint != 0)
    {
        // If the current character is a backslash that is not at the end of
        // the string, skip the backslash but copy the following character
        // verbatim into the argument string.
        if (*parsePoint == '\\' && *(parsePoint + 1) != 0)
        {
            parsePoint++;
        }

        // Otherwise, if not within a quoted substring...
        else if (quoteChar == 0)
        {
            // Whitespace marks the end of the argument.
            if (isspace(*parsePoint))
            {
                parsePoint++;
                break;
            }

            // If the character is a quote character, enter quoted substring mode.
            if (*parsePoint == '"' || *parsePoint == '\'')
            {
                quoteChar = *parsePoint++;
                continue;
            }
        }

        // Otherwise, the parse point is within a quoted substring, so...
        else
        {
            // A corresponding quote character marks the end of the quoted string.
            if (*parsePoint == quoteChar)
            {
                quoteChar = 0;
                parsePoint++;
                continue;
            }
        }

        // Copy the current character to the end of the argument string.
        *argEnd++ = *parsePoint++;
    }

    // Terminate the argument string.
    *argEnd = 0;

    return true;
}

static size_t CountOptionSets(OptionSet ** optSets)
{
    size_t count = 0;
    for (; *optSets != nullptr; optSets++)
        count++;
    return count;
}

static size_t CountAllOptions(OptionSet ** optSets)
{
    size_t count = 0;
    for (; *optSets != nullptr; optSets++)
        for (OptionDef * optDef = (*optSets)->OptionDefs; optDef->Name != nullptr; optDef++)
            count++;
    return count;
}

static void FindOptionByIndex(OptionSet ** optSets, int optIndex, OptionSet *& optSet, OptionDef *& optDef)
{
    for (optSet = *optSets; optSet != nullptr; optSet = *++optSets)
        for (optDef = (*optSets)->OptionDefs; optDef->Name != nullptr; optDef++)
            if (optIndex-- == 0)
                return;
    optSet = nullptr;
    optDef = nullptr;
}

static void FindOptionById(OptionSet ** optSets, int optId, OptionSet *& optSet, OptionDef *& optDef)
{
    for (optSet = *optSets; optSet != nullptr; optSet = *++optSets)
        for (optDef = (*optSets)->OptionDefs; optDef->Name != nullptr; optDef++)
            if (optDef->Id == optId)
                return;
    optSet = nullptr;
    optDef = nullptr;
}

static const char ** MakeUniqueHelpGroupNamesList(OptionSet * optSets[])
{
    size_t numOptSets = CountOptionSets(optSets);
    size_t numGroups  = 0;

    const char ** groupNames = static_cast<const char **>(chip::Platform::MemoryAlloc(sizeof(const char *) * (numOptSets + 1)));
    if (groupNames == nullptr)
        return nullptr;

    for (size_t optSetIndex = 0; optSetIndex < numOptSets; optSetIndex++)
    {
        if (optSets[optSetIndex] != nullptr && optSets[optSetIndex]->OptionDefs[0].Name != nullptr)
        {
            for (size_t i = 0; i < numGroups; i++)
                if (strcasecmp(groupNames[i], optSets[optSetIndex]->HelpGroupName) == 0)
                    goto skipDup;
            groupNames[numGroups++] = optSets[optSetIndex]->HelpGroupName;
        skipDup:;
        }
    }

    groupNames[numGroups] = nullptr;

    return groupNames;
}

static void PutStringWithNewLine(FILE * s, const char * str)
{
    size_t strLen = strlen(str);
    fputs(str, s);
    if (strLen == 0 || str[strLen - 1] != '\n')
        fputs("\n", s);
}

static void PutStringWithBlankLine(FILE * s, const char * str)
{
    size_t strLen = strlen(str);
    fputs(str, s);
    if (strLen < 1 || str[strLen - 1] != '\n')
        fputs("\n", s);
    if (strLen < 2 || str[strLen - 2] != '\n')
        fputs("\n", s);
}

#if CHIP_CONFIG_ENABLE_ARG_PARSER_VALIDITY_CHECKS

static bool SanityCheckOptions(OptionSet * optSets[])
{
    bool res = true;

    // Verify OptionHandler pointer
    for (OptionSet ** optSetP = optSets; *optSetP != nullptr; optSetP++)
    {
        if ((*optSetP)->OptionHandler == nullptr)
        {
            PrintArgError("INTERNAL ERROR: Null OptionHandler in OptionSet (%s)\n", (*optSetP)->HelpGroupName);
            res = false;
        }
    }

    // Verify that no two option sets use the same short option character.
    // (Re-use of the same short option character is allowed within a single option set
    // to allow for aliasing of long options).
    for (OptionSet ** optSetP = optSets; *optSetP != nullptr; optSetP++)
        for (OptionDef * optionDef = (*optSetP)->OptionDefs; optionDef->Name != nullptr; optionDef++)
            if (IsShortOptionChar(optionDef->Id))
            {
                for (OptionSet ** optSetP2 = optSets; *optSetP2 != nullptr; optSetP2++)
                    if (optSetP2 != optSetP)
                    {
                        for (OptionDef * optionDef2 = (*optSetP2)->OptionDefs; optionDef2->Name != nullptr; optionDef2++)
                            if (optionDef->Id == optionDef2->Id)
                            {
                                PrintArgError("INTERNAL ERROR: Multiple command line options configured to use "
                                              "the same short option character (-%c): --%s, --%s\n",
                                              optionDef->Id, optionDef->Name, optionDef2->Name);
                                res = false;
                            }
                    }
            }

    return res;
}

#endif // CHIP_CONFIG_ENABLE_ARG_PARSER_VALIDITY_CHECKS

} // namespace ArgParser
} // namespace chip

#endif // CHIP_CONFIG_ENABLE_ARG_PARSER
