/*
 *    Copyright (c) 2020-2023 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 macros, constants, and interfaces for a
 *      platform-independent logging interface for the chip SDK.
 *
 */

#include "TextOnlyLogging.h"

#include <lib/core/CHIPConfig.h>
#include <lib/support/CHIPMem.h>

#include <platform/logging/LogV.h>

#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include <atomic>

#if CHIP_PW_TOKENIZER_LOGGING
#include "pw_tokenizer/encode_args.h"
#endif

namespace chip {
namespace Logging {

#if _CHIP_USE_LOGGING

#if CHIP_PW_TOKENIZER_LOGGING

void HandleTokenizedLog(uint32_t levels, pw_tokenizer_Token token, pw_tokenizer_ArgTypes types, ...)
{
    uint8_t encoded_message[PW_TOKENIZER_CFG_ENCODING_BUFFER_SIZE_BYTES];

    memcpy(encoded_message, &token, sizeof(token));

    va_list args;
    va_start(args, types);
    // Use the C argument encoding API, since the C++ API requires C++17.
    const size_t encoded_size = sizeof(token) +
        pw_tokenizer_EncodeArgs(types, args, encoded_message + sizeof(token), sizeof(encoded_message) - sizeof(token));
    va_end(args);

    uint8_t log_category  = levels >> 8 & 0xFF;
    uint8_t log_module    = levels & 0xFF;
    char * logging_buffer = nullptr;

    // To reduce the number of alloc/free that is happening we will use a stack
    // buffer when buffer required to log is small.
    char stack_buffer[32];
    char * allocated_buffer     = nullptr;
    size_t required_buffer_size = 2 * encoded_size + 1;

    if (required_buffer_size > sizeof(stack_buffer))
    {
        allocated_buffer = (char *) chip::Platform::MemoryAlloc(required_buffer_size);
        if (allocated_buffer)
        {
            logging_buffer = allocated_buffer;
        }
    }
    else
    {
        logging_buffer = stack_buffer;
    }

    if (logging_buffer)
    {
        for (size_t i = 0; i < encoded_size; i++)
        {
            sprintf(logging_buffer + 2 * i, "%02x", encoded_message[i]);
        }
        logging_buffer[2 * encoded_size] = '\0';
        Log(log_module, log_category, "%s", logging_buffer);
    }
    if (allocated_buffer)
    {
        chip::Platform::MemoryFree(allocated_buffer);
    }
}

#endif

namespace {

std::atomic<LogRedirectCallback_t> sLogRedirectCallback{ nullptr };

/*
 * Array of strings containing the names for each of the chip log modules.
 *
 * NOTE: The names must be in the order defined in the LogModule enumeration.
 */
static const char ModuleNames[kLogModule_Max][kMaxModuleNameLen + 1] = {
    "-",   // None
    "IN",  // Inet
    "BLE", // BLE
    "ML",  // MessageLayer
    "SM",  // SecurityManager
    "EM",  // ExchangeManager
    "TLV", // TLV
    "ASN", // ASN1
    "CR",  // Crypto
    "CTL", // Controller
    "AL",  // Alarm
    "SC",  // SecureChannel
    "BDX", // BulkDataTransfer
    "DMG", // DataManagement
    "DC",  // DeviceControl
    "DD",  // DeviceDescription
    "ECH", // Echo
    "FP",  // FabricProvisioning
    "NP",  // NetworkProvisioning
    "SD",  // ServiceDirectory
    "SP",  // ServiceProvisioning
    "SWU", // SoftwareUpdate
    "FS",  // FailSafe
    "TS",  // TimeService
    "HB",  // Heartbeat
    "CSL", // chipSystemLayer
    "EVL", // Event Logging
    "SPT", // Support
    "TOO", // chipTool
    "ZCL", // Zcl
    "SH",  // Shell
    "DL",  // DeviceLayer
    "SPL", // SetupPayload
    "SVR", // AppServer
    "DIS", // Discovery
    "IM",  // InteractionModel
    "TST", // Test
    "OSS", // OperationalSessionSetup
    "ATM", // Automation
    "CSM", // CASESessionManager
    "ICD", // ICD
    "FS",  // FabricSync
};

} // namespace

const char * GetModuleName(LogModule module)
{
    return ModuleNames[(module < kLogModule_Max) ? module : kLogModule_NotSpecified];
}

void SetLogRedirectCallback(LogRedirectCallback_t callback)
{
    sLogRedirectCallback.store(callback);
}

/**
 * Log, to the platform-specified mechanism, the specified log
 * message, @a msg, for the specified module, @a module, in the
 * provided category, @a category.
 *
 * @param[in] module    A LogModule enumeration indicating the
 *                      source of the chip package module that
 *                      generated the log message. This must be
 *                      translated within the function to a module
 *                      name for inclusion in the log message.
 * @param[in] category  A LogCategory enumeration indicating the
 *                      category of the log message. The category
 *                      may be filtered in or out if
 *                      CHIP_LOG_FILTERING was asserted.
 * @param[in] msg       A pointer to a NULL-terminated C string with
 *                      C Standard Library-style format specifiers
 *                      containing the log message to be formatted and
 *                      logged.
 * @param[in] ...       A variadic argument list whose elements should
 *                      correspond to the format specifiers in @a msg.
 *
 */
void Log(uint8_t module, uint8_t category, const char * msg, ...)
{

    va_list v;
    va_start(v, msg);
    LogV(module, category, msg, v);
    va_end(v);
}

void LogV(uint8_t module, uint8_t category, const char * msg, va_list args)
{
    const char * moduleName        = GetModuleName(static_cast<LogModule>(module));
    LogRedirectCallback_t redirect = sLogRedirectCallback.load();
    if (redirect != nullptr)
    {
        redirect(moduleName, category, msg, args);
    }
    else
    {
        Platform::LogV(moduleName, category, msg, args);
    }
}

#if CHIP_LOG_FILTERING
std::atomic<uint8_t> gLogFilter(kLogCategory_Max);

uint8_t GetLogFilter()
{
    return gLogFilter.load();
}

void SetLogFilter(uint8_t category)
{
    gLogFilter.store(category);
}

bool IsCategoryEnabled(uint8_t category)
{
    return (category <= GetLogFilter());
}
#endif // CHIP_LOG_FILTERING

#endif // _CHIP_USE_LOGGING

} // namespace Logging
} // namespace chip
