/*
 *
 *    Copyright (c) 2018 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
 *          Provides implementations for the OpenWeave and LwIP logging functions
 *          on Nordic nRF52 platforms.
 */

#define NRF_LOG_MODULE_NAME weave

#include "nrf_log.h"

#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
#include <Weave/Support/logging/WeaveLogging.h>

#if WEAVE_DEVICE_CONFIG_ENABLE_THREAD
#include <openthread/platform/logging.h>
#endif // WEAVE_DEVICE_CONFIG_ENABLE_THREAD

// If deferred logging is NOT enabled, do bother calling the nRF5 SDK nrf_log_push() function.
#if !NRF_LOG_DEFERRED
#undef NRF_LOG_PUSH
#define NRF_LOG_PUSH(x) (x)
#endif

using namespace ::nl::Weave;
using namespace ::nl::Weave::DeviceLayer;
using namespace ::nl::Weave::DeviceLayer::Internal;

namespace {

void GetModuleName(char *buf, uint8_t module)
{
    if (module == ::nl::Weave::Logging::kLogModule_DeviceLayer)
    {
        memcpy(buf, "DL", 3);
    }
    else
    {
        ::nl::Weave::Logging::GetModuleName(buf, module);
    }
}

} // unnamed namespace

namespace nl {
namespace Weave {
namespace DeviceLayer {

/**
 * Called whenever a log message is emitted by Weave or LwIP.
 *
 * This function is intended be overridden by the application to, e.g.,
 * schedule output of queued log entries.
 */
void __attribute__((weak)) OnLogOutput(void)
{
}

} // namespace DeviceLayer
} // namespace Weave
} // namespace nl


NRF_LOG_MODULE_REGISTER();

namespace nl {
namespace Weave {
namespace Logging {

/**
 * OpenWeave log output function.
 */
void Log(uint8_t module, uint8_t category, const char *msg, ...)
{
    va_list v;

    (void)module;
    (void)category;

    va_start(v, msg);

#if NRF_LOG_ENABLED

    if (IsCategoryEnabled(category))
    {
        {
            char formattedMsg[WEAVE_DEVICE_CONFIG_LOG_MESSAGE_MAX_SIZE];
            size_t prefixLen;

            constexpr size_t maxPrefixLen = nlWeaveLoggingModuleNameLen + 3;
            static_assert(sizeof(formattedMsg) > maxPrefixLen);

            // Form the log prefix, e.g. "[DL] "
            formattedMsg[0] = '[';
            ::GetModuleName(formattedMsg + 1, module);
            prefixLen = strlen(formattedMsg);
            formattedMsg[prefixLen++] = ']';
            formattedMsg[prefixLen++] = ' ';

            // Append the log message.
            vsnprintf(formattedMsg + prefixLen, sizeof(formattedMsg) - prefixLen, msg, v);

            // Invoke the NRF logging library to log the message.
            switch (category) {
            case kLogCategory_Error:
                NRF_LOG_ERROR("%s", NRF_LOG_PUSH(formattedMsg));
                break;
            case kLogCategory_Progress:
            case kLogCategory_Retain:
            default:
                NRF_LOG_INFO("%s", NRF_LOG_PUSH(formattedMsg));
                break;
            case kLogCategory_Detail:
                NRF_LOG_DEBUG("%s", NRF_LOG_PUSH(formattedMsg));
                break;
            }
        }

        // Let the application know that a log message has been emitted.
        DeviceLayer::OnLogOutput();
    }

#endif // NRF_LOG_ENABLED

    va_end(v);
}

} // namespace Logging
} // namespace Weave
} // namespace nl


#undef NRF_LOG_MODULE_NAME
#define NRF_LOG_MODULE_NAME lwip
NRF_LOG_MODULE_REGISTER();

/**
 * LwIP log output function.
 */
extern "C"
void LwIPLog(const char *msg, ...)
{
    va_list v;

    va_start(v, msg);

#if NRF_LOG_ENABLED
    {
        char formattedMsg[WEAVE_DEVICE_CONFIG_LOG_MESSAGE_MAX_SIZE];

        // Append the log message.
        size_t len = vsnprintf(formattedMsg, sizeof(formattedMsg), msg, v);

        while (len > 0 && isspace(formattedMsg[len-1]))
        {
            len--;
            formattedMsg[len] = 0;
        }

        // Invoke the NRF logging library to log the message.
        NRF_LOG_DEBUG("%s", NRF_LOG_PUSH(formattedMsg));
    }

    // Let the application know that a log message has been emitted.
    DeviceLayer::OnLogOutput();

#endif // NRF_LOG_ENABLED

    va_end(v);
}

#if WEAVE_DEVICE_CONFIG_ENABLE_THREAD

#undef NRF_LOG_MODULE_NAME
#define NRF_LOG_MODULE_NAME thread
NRF_LOG_MODULE_REGISTER();

extern "C"
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
    va_list v;

    (void)aLogLevel;
    (void)aLogRegion;

    va_start(v, aFormat);

#if NRF_LOG_ENABLED
    {
        char formattedMsg[WEAVE_DEVICE_CONFIG_LOG_MESSAGE_MAX_SIZE];

        // Append the log message.
        vsnprintf(formattedMsg, sizeof(formattedMsg), aFormat, v);

        // Invoke the NRF logging library to log the message.
        switch (aLogLevel) {
        case OT_LOG_LEVEL_CRIT:
            NRF_LOG_ERROR("%s", NRF_LOG_PUSH(formattedMsg));
            break;
        case OT_LOG_LEVEL_WARN:
            NRF_LOG_WARNING("%s", NRF_LOG_PUSH(formattedMsg));
            break;
        case OT_LOG_LEVEL_NOTE:
        case OT_LOG_LEVEL_INFO:
        default:
            NRF_LOG_INFO("%s", NRF_LOG_PUSH(formattedMsg));
            break;
        case OT_LOG_LEVEL_DEBG:
            NRF_LOG_DEBUG("%s", NRF_LOG_PUSH(formattedMsg));
            break;
        }
    }

    // Let the application know that a log message has been emitted.
    DeviceLayer::OnLogOutput();

#endif // NRF_LOG_ENABLED

    va_end(v);
}

#endif // WEAVE_DEVICE_CONFIG_ENABLE_THREAD
