/**
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2018 Google LLC.
 *    Copyright (c) 2016-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 defines message helper functions in CHIP interaction model
 *
 */

#include "MessageDefHelper.h"
#include <algorithm>
#include <app/AppConfig.h>
#include <app/InteractionModelRevision.h>
#include <app/util/basic-types.h>
#include <inttypes.h>
#include <lib/support/logging/CHIPLogging.h>
#include <stdarg.h>
#include <stdio.h>

namespace chip {
namespace app {
#if CHIP_CONFIG_IM_PRETTY_PRINT && CHIP_DETAIL_LOGGING
// this is used to run in signle thread for IM message debug purpose
namespace {
uint32_t gPrettyPrintingDepthLevel = 0;
char gLineBuffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
size_t gCurLineBufferSize = 0;
} // namespace

void PrettyPrintIMBlankLine()
{
    if (gCurLineBufferSize)
    {
        // Don't need to explicitly NULL-terminate the string because
        // snprintf takes care of that.
        ChipLogDetail(DataManagement, "%s", gLineBuffer);
        gCurLineBufferSize = 0;
    }

    for (uint32_t i = 0; i < gPrettyPrintingDepthLevel; i++)
    {
        if (sizeof(gLineBuffer) > gCurLineBufferSize)
        {
            size_t sizeLeft = sizeof(gLineBuffer) - gCurLineBufferSize;
            size_t ret      = (size_t) (snprintf(gLineBuffer + gCurLineBufferSize, sizeLeft, "\t"));
            if (ret > 0)
            {
                gCurLineBufferSize += std::min(ret, sizeLeft);
            }
        }
    }
}

void PrettyPrintIM(bool aIsNewLine, const char * aFmt, ...)
{
    va_list args;
    va_start(args, aFmt);

    if (aIsNewLine)
    {
        PrettyPrintIMBlankLine();
    }

    if (sizeof(gLineBuffer) > gCurLineBufferSize)
    {
        size_t sizeLeft = sizeof(gLineBuffer) - gCurLineBufferSize;
        size_t ret      = (size_t) (vsnprintf(gLineBuffer + gCurLineBufferSize, sizeLeft, aFmt, args));
        if (ret > 0)
        {
            gCurLineBufferSize += std::min(ret, sizeLeft);
        }
    }

    va_end(args);
}
void IncreaseDepth()
{
    gPrettyPrintingDepthLevel++;
}

void DecreaseDepth()
{
    gPrettyPrintingDepthLevel--;
}
#endif

#if CHIP_CONFIG_IM_PRETTY_PRINT
CHIP_ERROR CheckIMPayload(TLV::TLVReader & aReader, int aDepth, const char * aLabel)
{
    if (aDepth == 0)
    {
        PRETTY_PRINT("%s = ", aLabel);
    }
    else
    {
        if (TLV::IsContextTag(aReader.GetTag()))
        {
            PRETTY_PRINT("0x%" PRIx32 " = ", TLV::TagNumFromTag(aReader.GetTag()));
        }
        else if (TLV::IsProfileTag(aReader.GetTag()))
        {
            PRETTY_PRINT("0x%" PRIx32 "::0x%" PRIx32 " = ", TLV::ProfileIdFromTag(aReader.GetTag()),
                         TLV::TagNumFromTag(aReader.GetTag()));
        }
        else
        {
            // Anonymous tag, don't print anything
        }
    }

    switch (aReader.GetType())
    {
    case TLV::kTLVType_Structure:
        PRETTY_PRINT("{");
        break;

    case TLV::kTLVType_Array:
        PRETTY_PRINT_SAMELINE("[");
        PRETTY_PRINT("\t\t");
        break;

    case TLV::kTLVType_SignedInteger: {
        int64_t value_s64;

        ReturnErrorOnFailure(aReader.Get(value_s64));

        // TODO: Figure out how to not use PRId64 here, since it's not supported
        // on all libcs.
        PRETTY_PRINT_SAMELINE("%" PRId64 ", ", value_s64);
        break;
    }

    case TLV::kTLVType_UnsignedInteger: {
        uint64_t value_u64;

        ReturnErrorOnFailure(aReader.Get(value_u64));

        // TODO: Figure out how to not use PRIu64 here, since it's not supported
        // on all libcs.
        PRETTY_PRINT_SAMELINE("%" PRIu64 ", ", value_u64);
        break;
    }

    case TLV::kTLVType_FloatingPointNumber: {
        double value_fp;

        ReturnErrorOnFailure(aReader.Get(value_fp));

        PRETTY_PRINT_SAMELINE("%f, ", value_fp);
        break;
    }
    case TLV::kTLVType_Boolean: {
        bool value_b;

        ReturnErrorOnFailure(aReader.Get(value_b));

        PRETTY_PRINT_SAMELINE("%s, ", value_b ? "true" : "false");
        break;
    }

    case TLV::kTLVType_UTF8String: {
        char value_s[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];

#if CHIP_DETAIL_LOGGING
        uint32_t readerLen = aReader.GetLength();
#endif // CHIP_DETAIL_LOGGING
        CHIP_ERROR err = aReader.GetString(value_s, sizeof(value_s));
        VerifyOrReturnError(err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL, err);

        if (err == CHIP_ERROR_BUFFER_TOO_SMALL)
        {
            PRETTY_PRINT_SAMELINE("... (char string too long: %" PRIu32 " chars) ...", readerLen);
        }
        else
        {
            PRETTY_PRINT_SAMELINE("\"%s\" (%" PRIu32 " chars), ", value_s, readerLen);
        }
        break;
    }

    case TLV::kTLVType_ByteString: {
        uint8_t value_b[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
        uint32_t len, readerLen;

        readerLen = aReader.GetLength();

        CHIP_ERROR err = aReader.GetBytes(value_b, sizeof(value_b));
        VerifyOrReturnError(err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL, err);

        PRETTY_PRINT_SAMELINE("[");
        PRETTY_PRINT("\t\t");

        if (readerLen < sizeof(value_b))
        {
            len = readerLen;
        }
        else
        {
            len = sizeof(value_b);
        }

        if (err == CHIP_ERROR_BUFFER_TOO_SMALL)
        {
            PRETTY_PRINT_SAMELINE("... (byte string too long) ...");
        }
        else
        {
            for (size_t i = 0; i < len; i++)
            {
                PRETTY_PRINT_SAMELINE("0x%02x, ", value_b[i]);
            }
        }

        PRETTY_PRINT("] (%" PRIu32 " bytes)", readerLen);
        break;
    }

    case TLV::kTLVType_Null:
        PRETTY_PRINT_SAMELINE("NULL");
        break;

    default:
        PRETTY_PRINT_SAMELINE("--");
        break;
    }

    if (aReader.GetType() == TLV::kTLVType_Structure || aReader.GetType() == TLV::kTLVType_Array)
    {
        const char terminating_char = (aReader.GetType() == TLV::kTLVType_Structure) ? '}' : ']';
        TLV::TLVType type;

        IgnoreUnusedVariable(terminating_char);

        ReturnErrorOnFailure(aReader.EnterContainer(type));

        CHIP_ERROR err;
        while ((err = aReader.Next()) == CHIP_NO_ERROR)
        {
            PRETTY_PRINT_INCDEPTH();

            ReturnErrorOnFailure(CheckIMPayload(aReader, aDepth + 1, aLabel));

            PRETTY_PRINT_DECDEPTH();
        }

        PRETTY_PRINT("%c,", terminating_char);

        ReturnErrorOnFailure(aReader.ExitContainer(type));
    }

    return CHIP_NO_ERROR;
}
#endif // CHIP_CONFIG_IM_PRETTY_PRINT

}; // namespace app
}; // namespace chip
