/*
 *   Copyright (c) 2021 Project CHIP Authors
 *   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.
 *
 */
#include "TraceHandlers.h"

#include <mutex>
#include <stdint.h>
#include <string>
#include <vector>

#include <lib/support/BytesToHex.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <transport/TraceMessage.h>

// For `s` std::string literal suffix
using namespace std::string_literals;

namespace chip {
namespace trace {

#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
namespace {

// Handles the output from the trace handlers.
class TraceOutput
{
public:
    ~TraceOutput() { UnregisterAllStreams(); }

    void RegisterStream(TraceStream * stream)
    {
        std::lock_guard<std::mutex> guard(mLock);
        mStreams.push_back(stream);
    }

    void UnregisterAllStreams()
    {
        for (auto stream : mStreams)
        {
            delete stream;
        }
        mStreams.clear();
    }

    void StartEvent(const std::string & label)
    {
        std::lock_guard<std::mutex> guard(mLock);
        for (auto stream : mStreams)
        {
            stream->StartEvent(label);
        }
    }

    void AddField(const std::string & tag, const std::string & data)
    {
        std::lock_guard<std::mutex> guard(mLock);
        for (auto stream : mStreams)
        {
            stream->AddField(tag, data);
        }
    }

    void FinishEvent()
    {
        std::lock_guard<std::mutex> guard(mLock);
        for (auto stream : mStreams)
        {
            stream->FinishEvent();
        }
    }

    bool HasStreamAvailable() const
    {
        std::lock_guard<std::mutex> guard(mLock);
        return (mStreams.size());
    }

private:
    mutable std::mutex mLock;
    std::vector<TraceStream *> mStreams;
};

TraceOutput gTraceOutputs;

std::string AsJsonKey(const std::string & key, const std::string & value, bool prepend_comma)
{
    return (prepend_comma ? ", "s : ""s) + "\""s + key + "\": " + value;
}

std::string AsFirstJsonKey(const std::string & key, const std::string & value)
{
    return AsJsonKey(key, value, /* prepend_comma = */ false);
}

std::string AsNextJsonKey(const std::string & key, const std::string & value)
{
    return AsJsonKey(key, value, /* prepend_comma = */ true);
}

std::string AsJsonString(const std::string & value)
{
    return "\""s + value + "\""s;
}

std::string AsJsonString(const Transport::PeerAddress * peerAddress)
{
    char convBuf[Transport::PeerAddress::kMaxToStringSize] = { 0 };

    peerAddress->ToString(convBuf);
    return AsJsonString(convBuf);
}

std::string AsJsonBool(bool isTrue)
{
    return isTrue ? "true"s : "false"s;
}

std::string AsJsonHexString(const uint8_t * buf, size_t bufLen)
{
    // Avoid hex conversion that would fail on empty
    if (bufLen == 0)
    {
        return AsJsonString("");
    }

    // Fill a buffer long enough for the hex conversion, that will be overwritten
    std::vector<char> hexBuf(2 * bufLen, '\0');

    CHIP_ERROR status = Encoding::BytesToLowercaseHexBuffer(buf, bufLen, hexBuf.data(), hexBuf.size());

    // Static conditions exist that should ensure never failing. Catch failure in an assert.
    if (status != CHIP_NO_ERROR)
    {
        ChipLogError(Support, "Unexpected failure: %" CHIP_ERROR_FORMAT, status.Format());
        VerifyOrDie(status == CHIP_NO_ERROR);
    }

    return AsJsonString(std::string(hexBuf.data(), hexBuf.size()));
}

std::string PacketHeaderToJson(const PacketHeader * packetHeader)
{
    std::string jsonBody;

    uint32_t messageCounter = packetHeader->GetMessageCounter();
    jsonBody += AsFirstJsonKey("msg_counter", std::to_string(messageCounter));

    const Optional<NodeId> & sourceNodeId = packetHeader->GetSourceNodeId();
    if (sourceNodeId.HasValue())
    {
        jsonBody += AsNextJsonKey("source_node_id", std::to_string(sourceNodeId.Value()));
    }

    uint16_t sessionId                  = packetHeader->GetSessionId();
    const Optional<GroupId> & groupId   = packetHeader->GetDestinationGroupId();
    const Optional<NodeId> & destNodeId = packetHeader->GetDestinationNodeId();
    if (packetHeader->IsValidGroupMsg())
    {
        if (groupId.HasValue())
        {
            jsonBody += AsNextJsonKey("group_id", std::to_string(groupId.Value()));
        }

        jsonBody += AsNextJsonKey("group_key_hash", std::to_string(sessionId));
    }
    else if (destNodeId.HasValue())
    {
        jsonBody += AsNextJsonKey("dest_node_id", std::to_string(destNodeId.Value()));
    }

    jsonBody += AsNextJsonKey("session_id", std::to_string(sessionId));

    uint8_t messageFlags = packetHeader->GetMessageFlags();
    jsonBody += AsNextJsonKey("msg_flags", std::to_string(messageFlags));

    uint8_t securityFlags = packetHeader->GetSecurityFlags();
    jsonBody += AsNextJsonKey("security_flags", std::to_string(securityFlags));

    return jsonBody;
}

std::string PayloadHeaderToJson(const PayloadHeader * payloadHeader)
{

    std::string jsonBody;

    uint8_t exchangeFlags = payloadHeader->GetExchangeFlags();
    jsonBody += AsFirstJsonKey("exchange_flags", std::to_string(exchangeFlags));

    uint16_t exchangeId = payloadHeader->GetExchangeID();
    jsonBody += AsNextJsonKey("exchange_id", std::to_string(exchangeId));

    uint32_t protocolId = payloadHeader->GetProtocolID().ToFullyQualifiedSpecForm();
    jsonBody += AsNextJsonKey("protocol_id", std::to_string(protocolId));

    uint8_t protocolOpcode = payloadHeader->GetMessageType();
    jsonBody += AsNextJsonKey("protocol_opcode", std::to_string(protocolOpcode));

    bool isInitiator = payloadHeader->IsInitiator();
    jsonBody += AsNextJsonKey("is_initiator", AsJsonBool(isInitiator));

    bool needsAck = payloadHeader->NeedsAck();
    jsonBody += AsNextJsonKey("is_ack_requested", AsJsonBool(needsAck));

    const Optional<uint32_t> & acknowledgedMessageCounter = payloadHeader->GetAckMessageCounter();
    if (acknowledgedMessageCounter.HasValue())
    {
        jsonBody += AsNextJsonKey("acknowledged_msg_counter", std::to_string(acknowledgedMessageCounter.Value()));
    }

    return jsonBody;
}

void SecureMessageSentHandler(const TraceSecureMessageSentData * eventData)
{
    if (!gTraceOutputs.HasStreamAvailable())
    {
        return;
    }

    std::string jsonBody = "{";
    jsonBody += PacketHeaderToJson(eventData->packetHeader);
    jsonBody += ", ";
    jsonBody += PayloadHeaderToJson(eventData->payloadHeader);
    jsonBody += ", ";
    jsonBody += AsFirstJsonKey("payload_size", std::to_string(eventData->packetSize));
    jsonBody += ", ";
    jsonBody += AsFirstJsonKey("payload_hex", AsJsonHexString(eventData->packetPayload, eventData->packetSize));
    jsonBody += "}";

    gTraceOutputs.StartEvent(std::string{ kTraceMessageEvent } + "." + kTraceMessageSentDataFormat);
    gTraceOutputs.AddField("json", jsonBody);
    gTraceOutputs.FinishEvent();
}

void SecureMessageReceivedHandler(const TraceSecureMessageReceivedData * eventData)
{
    if (!gTraceOutputs.HasStreamAvailable())
    {
        return;
    }

    std::string jsonBody = "{";
    jsonBody += AsFirstJsonKey("peer_address", AsJsonString(eventData->peerAddress));
    jsonBody += ", ";
    jsonBody += PacketHeaderToJson(eventData->packetHeader);
    jsonBody += ", ";
    jsonBody += PayloadHeaderToJson(eventData->payloadHeader);
    jsonBody += ", ";
    jsonBody += AsFirstJsonKey("payload_size", std::to_string(eventData->packetSize));
    jsonBody += ", ";
    jsonBody += AsFirstJsonKey("payload_hex", AsJsonHexString(eventData->packetPayload, eventData->packetSize));
    jsonBody += "}";

    gTraceOutputs.StartEvent(std::string{ kTraceMessageEvent } + "." + kTraceMessageReceivedDataFormat);
    gTraceOutputs.AddField("json", jsonBody);
    gTraceOutputs.FinishEvent();

    // Note that `eventData->session` is currently ignored.
}

void TraceHandler(const char * type, const void * data, size_t size)
{
    if ((std::string{ type } == kTraceMessageSentDataFormat) && (size == sizeof(TraceSecureMessageSentData)))
    {
        SecureMessageSentHandler(reinterpret_cast<const TraceSecureMessageSentData *>(data));
    }
    else if ((std::string{ type } == kTraceMessageReceivedDataFormat) && (size == sizeof(TraceSecureMessageReceivedData)))
    {
        SecureMessageReceivedHandler(reinterpret_cast<const TraceSecureMessageReceivedData *>(data));
    }
}

} // namespace

void AddTraceStream(TraceStream * stream)
{
    gTraceOutputs.RegisterStream(stream);
}

void InitTrace()
{
    SetTransportTraceHook(TraceHandler);
}

void DeInitTrace()
{
    gTraceOutputs.UnregisterAllStreams();
}

#else
void AddTraceStream(TraceStream *) {}
void InitTrace() {}
void DeInitTrace() {}
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED

} // namespace trace
} // namespace chip
