//
// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "JSONTimelineDecoder.hpp"

#include <client/src/ProfilingUtils.hpp>

#include <string>

namespace armnn
{
namespace timelinedecoder
{

static const char *const CONNECTION = "connection";
static const char *const BACKEND_ID = "backendId";
static const char *const NAME = "name";
static const char *const TYPE = "type";
static const char *const WORKLOAD = "workload";
static const char *const WORKLOAD_EXECUTION = "workload_execution";
static const char *const INFERENCE = "inference";
static const char *const LAYER = "layer";
static const char *const ENTITY = "Entity";
static const char *const EVENTCLASS = "EventClass";
static const char *const EVENT = "Event";

JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEntity(const Entity& entity)
{
    JSONEntity jsonEntity(entity.m_Guid);
    jsonEntity.SetType(ENTITY);
    this->m_Model.jsonEntities.insert({entity.m_Guid, jsonEntity});
    return TimelineStatus::TimelineStatus_Success;
}

JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEventClass(const EventClass& eventClass)
{
    JSONEntity jsonEntity(eventClass.m_Guid);
    jsonEntity.SetType(EVENTCLASS);
    this->m_Model.eventClasses.insert({eventClass.m_Guid, eventClass});
    this->m_Model.jsonEntities.insert({eventClass.m_Guid, jsonEntity});
    return TimelineStatus::TimelineStatus_Success;
}

JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEvent(const Event& event)
{
    JSONEntity jsonEntity(event.m_Guid);
    jsonEntity.SetType(EVENT);
    this->m_Model.events.insert({event.m_Guid, event});
    this->m_Model.jsonEntities.insert({jsonEntity.GetGuid(), jsonEntity});
    return TimelineStatus::TimelineStatus_Success;
}

JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateLabel(const Label& label)
{
    this->m_Model.labels.insert({label.m_Guid, label});
    return TimelineStatus::TimelineStatus_Success;
}

JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateRelationship(const Relationship& relationship)
{
    if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::RetentionLink)
    {
        HandleRetentionLink(relationship);
    }
    else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::LabelLink)
    {
        HandleLabelLink(relationship);
    }
    else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::ExecutionLink)
    {
        HandleExecutionLink(relationship);
    }
    else
    {
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }

    return TimelineStatus::TimelineStatus_Success;
}


void JSONTimelineDecoder::HandleExecutionLink(const ITimelineDecoder::Relationship& relationship)
{
    uint64_t tailGuid = relationship.m_TailGuid;
    uint64_t headGuid = relationship.m_HeadGuid;

    if (m_Model.jsonEntities.count(relationship.m_HeadGuid) != 0)
    {
        JSONEntity& tailJSONEntity = m_Model.jsonEntities.at(tailGuid);
        JSONEntity& headJSONEntity = m_Model.jsonEntities.at(headGuid);
        tailJSONEntity.SetParent(headJSONEntity);
        m_Model.jsonEntities.insert({headGuid, headJSONEntity});
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
    else
    {
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
}

void JSONTimelineDecoder::HandleLabelLink(const ITimelineDecoder::Relationship& relationship)
{
    if (m_Model.labels.count(relationship.m_TailGuid) != 0)
    {
        if (m_Model.labels.at(relationship.m_TailGuid).m_Name == CONNECTION)
        {
            HandleConnectionLabel(relationship);
        }
        else if (m_Model.labels.at(relationship.m_TailGuid).m_Name == BACKEND_ID)
        {
            HandleBackendIdLabel(relationship);
        }
        else if (m_Model.labels.at(relationship.m_TailGuid).m_Name == NAME)
        {
            HandleNameLabel(relationship);
        }
        else if (m_Model.labels.at(relationship.m_TailGuid).m_Name == TYPE)
        {
            HandleTypeLabel(relationship);
        }
        else
        {
            m_Model.relationships.insert({relationship.m_Guid, relationship});
        }
    } else
    {
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
}

void JSONTimelineDecoder::HandleTypeLabel(const ITimelineDecoder::Relationship& relationship)
{
    if (m_Model.relationships.count(relationship.m_HeadGuid) != 0)
    {
        Relationship labelRelation = m_Model.relationships.at(relationship.m_HeadGuid);
        if (m_Model.jsonEntities.count(labelRelation.m_HeadGuid) != 0)
        {
            JSONEntity& headEntity = m_Model.jsonEntities.at(labelRelation.m_HeadGuid);
            std::string type = m_Model.labels.at(labelRelation.m_TailGuid).m_Name;
            headEntity.SetType(type);
        }
    }
    else
    {
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
}

void JSONTimelineDecoder::HandleNameLabel(const ITimelineDecoder::Relationship& relationship)
{
    if (m_Model.relationships.count(relationship.m_HeadGuid) != 0)
    {
        Relationship labelRelation = m_Model.relationships.at(relationship.m_HeadGuid);
        JSONEntity& headEntity = m_Model.jsonEntities.at(labelRelation.m_HeadGuid);
        std::string name = m_Model.labels.at(labelRelation.m_TailGuid).m_Name;
        headEntity.SetName(name);
    }
    else
    {
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
}

void JSONTimelineDecoder::HandleBackendIdLabel(const ITimelineDecoder::Relationship& relationship)
{
    if (m_Model.relationships.count(relationship.m_HeadGuid) != 0)
    {
        Relationship labelRelation = m_Model.relationships.at(relationship.m_HeadGuid);
        JSONEntity& headEntity = m_Model.jsonEntities.at(labelRelation.m_HeadGuid);
        std::string backendName = m_Model.labels.at(labelRelation.m_TailGuid).m_Name;
        headEntity.extendedData.insert({BACKEND_ID, backendName});
    }
    else
    {
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
}

void JSONTimelineDecoder::HandleConnectionLabel(const ITimelineDecoder::Relationship& relationship)
{
    if (m_Model.relationships.count(relationship.m_HeadGuid) != 0)
    {
        Relationship retentionRelation = m_Model.relationships.at(relationship.m_HeadGuid);
        JSONEntity& headEntity = m_Model.jsonEntities.at(retentionRelation.m_HeadGuid);
        JSONEntity& tailEntity = m_Model.jsonEntities.at(retentionRelation.m_TailGuid);
        headEntity.AddConnection(headEntity, tailEntity);
    }
    else
    {
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
}

void JSONTimelineDecoder::HandleRetentionLink(const ITimelineDecoder::Relationship& relationship)
{
    if (m_Model.jsonEntities.count(relationship.m_TailGuid) != 0 && m_Model.jsonEntities
    .count(relationship.m_HeadGuid) != 0)
    {
        JSONEntity& tailJSONEntity = m_Model.jsonEntities.at(relationship.m_TailGuid);
        JSONEntity& headJSONEntity = m_Model.jsonEntities.at(relationship.m_HeadGuid);
        tailJSONEntity.SetParent(headJSONEntity);
        m_Model.jsonEntities.insert({relationship.m_HeadGuid, headJSONEntity});
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
    else
    {
        m_Model.relationships.insert({relationship.m_Guid, relationship});
    }
}

void JSONTimelineDecoder::JSONEntity::SetParent(JSONEntity& parent)
{
    parent.childEntities.push_back(GetGuid());
}

void JSONTimelineDecoder::PrintJSON(JSONTimelineDecoder::JSONEntity& rootEntity, std::ostream& os)
{
    std::string jsonString = GetJSONString(rootEntity);
    os << jsonString;
}

std::string JSONTimelineDecoder::GetJSONString(JSONTimelineDecoder::JSONEntity& rootEntity)
{
    int counter = 0;
    std::string json;
    json.append("{\n");
    if(rootEntity.GetType() != "")
    {
        json.append("\tArmNN");
        json.append(": {\n");

        for (uint64_t childEntityId : rootEntity.childEntities)
        {
            JSONEntity& childEntity = this->m_Model.jsonEntities.at(childEntityId);
            json.append(GetJSONEntityString(childEntity, counter));
        }
    }
    json.append("}\n");
    return json;
}

std::string JSONTimelineDecoder::GetJSONEntityString(JSONTimelineDecoder::JSONEntity& entity, int& counter)
{
    std::string jsonEntityString;
    if(entity.GetType() == LAYER)
    {
        return GetLayerJSONString(entity, counter, jsonEntityString);
    }
    else if (entity.GetType() == WORKLOAD)
    {
        return GetWorkloadJSONString(entity, counter, jsonEntityString);
    }
    else if (entity.GetType() == WORKLOAD_EXECUTION)
    {
        return GetWorkloadExecutionJSONString(entity, jsonEntityString);
    }
    else if (entity.GetType() == INFERENCE)
    {
        return jsonEntityString;
    }
    else
    {
        for (uint64_t child_entity_id : entity.childEntities)
        {
            JSONEntity& childEntity = this->m_Model.jsonEntities.at(child_entity_id);
            jsonEntityString.append(GetJSONEntityString(childEntity, ++counter));
        }
        return jsonEntityString;
    }
}

std::string JSONTimelineDecoder::GetWorkloadExecutionJSONString(const JSONTimelineDecoder::JSONEntity& entity,
                                                                std::string& jsonEntityString) const
{
    if(entity.childEntities.size() < 2)
    {
        throw arm::pipe::ProfilingException(
            "Workload Execution Entity Packet does not have the expected Event packets attached");
    }
    JSONEntity jsonEventOne = entity.childEntities[0];
    JSONEntity jsonEventTwo = entity.childEntities[1];

    Event event1 = m_Model.events.at(jsonEventOne.GetGuid());
    Event event2 = m_Model.events.at(jsonEventTwo.GetGuid());

    uint64_t wall_clock_time = event2.m_TimeStamp - event1.m_TimeStamp;
    jsonEntityString.append("\t\t\t");
    jsonEntityString.append("raw : [");
    jsonEntityString.append(std::to_string(wall_clock_time));
    jsonEntityString.append("], \n");
    jsonEntityString.append("\t\t\t");
    jsonEntityString.append("unit : us,\n");
    jsonEntityString.append("\t\t\t");
    jsonEntityString.append("}\n");

    return jsonEntityString;
}

std::string JSONTimelineDecoder::GetWorkloadJSONString(const JSONTimelineDecoder::JSONEntity& entity, int& counter,
                                                       std::string& jsonEntityString)
{
    jsonEntityString.append("\t\t\t");
    jsonEntityString.append("backendId :");
    jsonEntityString.append(entity.extendedData.at(BACKEND_ID));
    jsonEntityString.append(",\n");
    for (uint64_t child_entity_id : entity.childEntities)
    {
        JSONEntity &childEntity = m_Model.jsonEntities.at(child_entity_id);
        jsonEntityString.append(GetJSONEntityString(childEntity, ++counter));
    }
    return jsonEntityString;
}

std::string JSONTimelineDecoder::GetLayerJSONString(JSONTimelineDecoder::JSONEntity& entity, int& counter,
                                                    std::string& jsonEntityString)
{
    jsonEntityString.append("\t\t");
    jsonEntityString.append(entity.GetName());
    jsonEntityString.append("_");
    jsonEntityString.append(std::to_string(counter));
    jsonEntityString.append(": {\n");
    jsonEntityString.append("\t\t\t");
    jsonEntityString.append("type: Measurement,\n");
    for (uint64_t child_entity_id : entity.childEntities)
    {
        JSONEntity& childEntity = m_Model.jsonEntities.at(child_entity_id);
        jsonEntityString.append(GetJSONEntityString(childEntity, ++counter));
    }
    return jsonEntityString;
}

void JSONTimelineDecoder::JSONEntity::AddConnection(JSONEntity& headEntity, JSONEntity& connectedEntity)
{
    std::vector<uint64_t>::iterator it = std::find(headEntity.childEntities.begin(),
            headEntity.childEntities.end(), connectedEntity.GetGuid());
    headEntity.childEntities.erase(it);
    headEntity.connected_entities.push_back(connectedEntity.m_Guid);
}

uint64_t JSONTimelineDecoder::JSONEntity::GetGuid()
{
    return m_Guid;
}

const JSONTimelineDecoder::Model &JSONTimelineDecoder::GetModel()
{
    return m_Model;
}

void JSONTimelineDecoder::JSONEntity::SetName(std::string entityName)
{
    this->name = entityName;
}

std::string JSONTimelineDecoder::JSONEntity::GetName()
{
    return this->name;
}

void JSONTimelineDecoder::JSONEntity::SetType(std::string entityType)
{
    this->type = entityType;
}

std::string JSONTimelineDecoder::JSONEntity::GetType()
{
    return this->type;
}

}
}
