/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *
 *    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 functions to translate error codes used
 *      throughout the CHIP package into human-readable strings.
 *
 */

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include <inttypes.h>
#include <stdio.h>

#include <lib/core/CHIPCore.h>
#include <lib/support/CodeUtils.h>

namespace chip {

/**
 * Static buffer to store the formatted error string.
 */
static char sErrorStr[CHIP_CONFIG_ERROR_STR_SIZE];

/**
 * Linked-list of error formatter functions.
 */
static ErrorFormatter * sErrorFormatterList = nullptr;

/**
 * This routine returns a human-readable NULL-terminated C string
 * describing the provided error.
 *
 * @param[in] err                      The error for format and describe.
 *
 * @return A pointer to a NULL-terminated C string describing the
 *         provided error.
 */
DLL_EXPORT const char * ErrorStr(CHIP_ERROR err)
{
    char * formattedError   = sErrorStr;
    uint16_t formattedSpace = sizeof(sErrorStr);

#if CHIP_CONFIG_ERROR_SOURCE && !CHIP_CONFIG_SHORT_ERROR_STR

    const char * const file = err.GetFile();
    if (file != nullptr)
    {
        int n = snprintf(formattedError, formattedSpace, "%s:%u: ", file, err.GetLine());
        if (n > formattedSpace)
        {
            n = formattedSpace;
        }
        formattedError += n;
        formattedSpace = static_cast<uint16_t>(formattedSpace - n);
    }
    if (err == CHIP_NO_ERROR)
    {
        (void) snprintf(formattedError, formattedSpace, CHIP_NO_ERROR_STRING);
        return sErrorStr;
    }

#else // CHIP_CONFIG_ERROR_SOURCE && !CHIP_CONFIG_SHORT_ERROR_STR

    if (err == CHIP_NO_ERROR)
    {
        return CHIP_NO_ERROR_STRING;
    }

#endif // CHIP_CONFIG_ERROR_SOURCE && !CHIP_CONFIG_SHORT_ERROR_STR

    // Search the registered error formatter for one that will format the given
    // error code.
    for (const ErrorFormatter * errFormatter = sErrorFormatterList; errFormatter != nullptr; errFormatter = errFormatter->Next)
    {
        if (errFormatter->FormatError(formattedError, formattedSpace, err))
        {
            return sErrorStr;
        }
    }

    // Use a default formatting if no formatter found.
    FormatError(formattedError, formattedSpace, nullptr, err, nullptr);
    return sErrorStr;
}

/**
 * Add a new error formatter function to the global list of error formatters.
 *
 * @param[in] errFormatter             An ErrorFormatter structure containing a
 *                                     pointer to the new error function.  Note
 *                                     that a pointer to the supplied ErrorFormatter
 *                                     structure will be retained by the function.
 *                                     Thus the memory for the structure must
 *                                     remain reserved.
 */
DLL_EXPORT void RegisterErrorFormatter(ErrorFormatter * errFormatter)
{
    // Do nothing if a formatter with the same format function is already in the list.
    for (ErrorFormatter * existingFormatter = sErrorFormatterList; existingFormatter != nullptr;
         existingFormatter                  = existingFormatter->Next)
    {
        if (existingFormatter->FormatError == errFormatter->FormatError)
        {
            return;
        }
    }

    // Add the formatter to the global list.
    errFormatter->Next  = sErrorFormatterList;
    sErrorFormatterList = errFormatter;
}

/**
 * Remove an error formatter function from the global list of error formatters.
 *
 * @param[in] errFormatter             An ErrorFormatter structure containing a
 *                                     pointer to the new error function.
 */
DLL_EXPORT void DeregisterErrorFormatter(ErrorFormatter * errFormatter)
{
    // Remove the formatter if present
    for (ErrorFormatter ** lfp = &sErrorFormatterList; *lfp != nullptr; lfp = &(*lfp)->Next)
    {
        // Remove the formatter from the global list, if found.
        if (*lfp == errFormatter)
        {
            *lfp = errFormatter->Next;
        }
    }
}

#if !CHIP_CONFIG_CUSTOM_ERROR_FORMATTER

/**
 * Generates a human-readable NULL-terminated C string describing the provided error.
 *
 * @param[in] buf                   Buffer into which the error string will be placed.
 * @param[in] bufSize               Size of the supplied buffer in bytes.
 * @param[in] subsys                A short string describing the subsystem that originated
 *                                  the error, or NULL if the origin of the error is
 *                                  unknown/unavailable.  This string should be 10
 *                                  characters or less.
 * @param[in] err                   The error to be formatted.
 * @param[in] desc                  A string describing the cause or meaning of the error,
 *                                  or NULL if no such information is available.
 */
DLL_EXPORT void FormatError(char * buf, uint16_t bufSize, const char * subsys, CHIP_ERROR err, const char * desc)
{
#if CHIP_CONFIG_SHORT_ERROR_STR

    if (subsys == NULL)
    {
        (void) snprintf(buf, bufSize, "Error " CHIP_CONFIG_SHORT_FORM_ERROR_VALUE_FORMAT, err.AsInteger());
    }
    else
    {
        (void) snprintf(buf, bufSize, "Error %s:" CHIP_CONFIG_SHORT_FORM_ERROR_VALUE_FORMAT, subsys, err.AsInteger());
    }

#else // CHIP_CONFIG_SHORT_ERROR_STR

    const char * subsysSep = " ";
    const char * descSep   = ": ";

    if (subsys == nullptr)
    {
        subsys    = "";
        subsysSep = "";
    }
    if (desc == nullptr)
    {
        desc    = "";
        descSep = "";
    }

    (void) snprintf(buf, bufSize, "%s%sError 0x%08" PRIX32 "%s%s", subsys, subsysSep, err.AsInteger(), descSep, desc);

#endif // CHIP_CONFIG_SHORT_ERROR_STR
}

#endif // CHIP_CONFIG_CUSTOM_ERROR_FORMATTER

} // namespace chip
