/**
 *
 *    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 "protocols/interaction_model/StatusCode.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(Tag::kStatus), aStatusIB.mStatus);
    SuccessOrExit(mError);

    if (aStatusIB.mClusterStatus.HasValue())
    {
        mError = mpWriter->Put(TLV::ContextTag(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));
}

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
    static constexpr char generalFormat[] = "General error: " ChipLogFormatIMStatus;
    static 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(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
