/**
 *
 *    Copyright (c) 2020 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 Status Information Block in Interaction Model
 *
 */

#include "StatusIB.h"

#include "MessageDefHelper.h"

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

#include <app/AppConfig.h>
#include <lib/core/CHIPCore.h>

using namespace chip;
using namespace chip::TLV;
using namespace chip::Protocols::InteractionModel;

namespace chip {
namespace app {
CHIP_ERROR StatusIB::Parser::DecodeStatusIB(StatusIB & aStatusIB) const
{
    TLV::TLVReader reader;
    reader.Init(mReader);
    while (CHIP_NO_ERROR == reader.Next())
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case to_underlying(Tag::kStatus):
            ReturnErrorOnFailure(reader.Get(aStatusIB.mStatus));
            break;
        case to_underlying(Tag::kClusterStatus):
            ClusterStatus clusterStatus;
            ReturnErrorOnFailure(reader.Get(clusterStatus));
            aStatusIB.mClusterStatus.SetValue(clusterStatus);
            break;
        }
    }
    return CHIP_NO_ERROR;
}
#if CHIP_CONFIG_IM_PRETTY_PRINT
CHIP_ERROR StatusIB::Parser::PrettyPrint() const
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVReader reader;

    PRETTY_PRINT("StatusIB =");
    PRETTY_PRINT("{");

    // make a copy of the reader
    reader.Init(mReader);
    while (CHIP_NO_ERROR == (err = reader.Next()))
    {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
        switch (tagNum)
        {
        case to_underlying(Tag::kStatus):
#if CHIP_DETAIL_LOGGING
        {
            uint8_t status;
            ReturnErrorOnFailure(reader.Get(status));
            PRETTY_PRINT("\tstatus = " ChipLogFormatIMStatus ",", ChipLogValueIMStatus(static_cast<Status>(status)));
        }
#endif // CHIP_DETAIL_LOGGING
        break;
        case to_underlying(Tag::kClusterStatus):
#if CHIP_DETAIL_LOGGING
        {
            ClusterStatus clusterStatus;
            ReturnErrorOnFailure(reader.Get(clusterStatus));
            PRETTY_PRINT("\tcluster-status = 0x%x,", clusterStatus);
        }
#endif // CHIP_DETAIL_LOGGING
        break;
        default:
            PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
            break;
        }
    }

    PRETTY_PRINT("},");
    PRETTY_PRINT_BLANK_LINE();
    // if we have exhausted this container
    if (CHIP_END_OF_TLV == err)
    {
        err = CHIP_NO_ERROR;
    }
    ReturnErrorOnFailure(err);
    return reader.ExitContainer(mOuterContainerType);
}
#endif // CHIP_CONFIG_IM_PRETTY_PRINT

StatusIB::Builder & StatusIB::Builder::EncodeStatusIB(const StatusIB & aStatusIB)
{
    mError = mpWriter->Put(TLV::ContextTag(to_underlying(Tag::kStatus)), aStatusIB.mStatus);
    SuccessOrExit(mError);

    if (aStatusIB.mClusterStatus.HasValue())
    {
        mError = mpWriter->Put(TLV::ContextTag(to_underlying(Tag::kClusterStatus)), aStatusIB.mClusterStatus.Value());
        SuccessOrExit(mError);
    }

    EndOfContainer();
exit:
    return *this;
}

CHIP_ERROR StatusIB::ToChipError() const
{
    if (mStatus == Status::Success)
    {
        return CHIP_NO_ERROR;
    }

    if (mClusterStatus.HasValue())
    {
        return ChipError(ChipError::SdkPart::kIMClusterStatus, mClusterStatus.Value());
    }

    return ChipError(ChipError::SdkPart::kIMGlobalStatus, to_underlying(mStatus));
}

void StatusIB::InitFromChipError(CHIP_ERROR aError)
{
    if (aError.IsPart(ChipError::SdkPart::kIMClusterStatus))
    {
        mStatus        = Status::Failure;
        mClusterStatus = MakeOptional(aError.GetSdkCode());
        return;
    }

    mClusterStatus = NullOptional;
    if (aError == CHIP_NO_ERROR)
    {
        mStatus = Status::Success;
        return;
    }

    if (aError.IsPart(ChipError::SdkPart::kIMGlobalStatus))
    {
        mStatus = static_cast<Status>(aError.GetSdkCode());
        return;
    }

    mStatus = Status::Failure;
}

namespace {
bool FormatStatusIBError(char * buf, uint16_t bufSize, CHIP_ERROR err)
{
    if (!err.IsIMStatus())
    {
        return false;
    }

    const char * desc = nullptr;
#if !CHIP_CONFIG_SHORT_ERROR_STR
    constexpr char generalFormat[] = "General error: " ChipLogFormatIMStatus;
    constexpr char clusterFormat[] = "Cluster-specific error: 0x%02x";

    // Formatting an 8-bit int will take at most 2 chars, and replace the '%02x'
    // so a buffer big enough to hold our format string will also hold our
    // formatted string, as long as we account for the possible string formats.
    constexpr size_t statusNameMaxLength =
#define CHIP_IM_STATUS_CODE(name, spec_name, value)                                                                                \
        max(sizeof(#spec_name),
#include <protocols/interaction_model/StatusCodeList.h>
#undef CHIP_IM_STATUS_CODE
        static_cast<size_t>(0)
#define CHIP_IM_STATUS_CODE(name, spec_name, value)                                                                                \
        )
#include <protocols/interaction_model/StatusCodeList.h>
#undef CHIP_IM_STATUS_CODE
        ;
    constexpr size_t formattedSize = max(sizeof(generalFormat) + statusNameMaxLength, sizeof(clusterFormat));
    char formattedString[formattedSize];

    StatusIB status;
    status.InitFromChipError(err);
    if (status.mClusterStatus.HasValue())
    {
        snprintf(formattedString, formattedSize, clusterFormat, status.mClusterStatus.Value());
    }
    else
    {
        snprintf(formattedString, formattedSize, generalFormat, ChipLogValueIMStatus(status.mStatus));
    }
    desc = formattedString;
#endif // !CHIP_CONFIG_SHORT_ERROR_STR
    FormatError(buf, bufSize, "IM", err, desc);

    return true;
}
} // anonymous namespace

void StatusIB::RegisterErrorFormatter()
{
    static ErrorFormatter sStatusIBErrorFormatter = { FormatStatusIBError, nullptr };

    ::RegisterErrorFormatter(&sStatusIBErrorFormatter);
}

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