/*!
##############################################################################
# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
##############################################################################
*/

#ifndef _COVERAGE_TOOL_COVERAGE_PLUGIN_TRACE_SOURCES_H_
#define _COVERAGE_TOOL_COVERAGE_PLUGIN_TRACE_SOURCES_H_

#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include "MTI/ModelTraceInterface.h"

using namespace MTI;
using namespace std;

struct InstStat {
    uint64_t cnt;
    uint64_t size;
};

typedef std::map<uint32_t, InstStat> InstStatMap;

//Defining types for fields
enum enum_types {u32, boolT, u8};
typedef enum_types ValueTypes;

/*
 * Structure used to save field data
 */
struct TFields{
    ValueTypes t;
    MTI::ValueIndex index;
    void *value;
};
// Map of fields => Key -> Field name
typedef map<string, TFields> TraceFieldsMap;

/*
 * Structure used to pass field data between trace contexts
 */
struct TParams {
    void *value;
    ValueTypes t;
};
// Map of fields => Key -> Field name
typedef map<string, TParams> ParamsMap;

/*
 * Generic function to output errors
 */
bool Error(const char *msg)
{
    fprintf(stderr, "%s\n", msg);
    return false;
}

/*
 * Base class for Trace Source contexts
 *
 */
class TraceSourceContext {
    public:
        string name; //Trace source name
        TraceFieldsMap fields; //Fields to be used for the event
        MTI::EventClass *event_class; //Event object to register callback
        ParamsMap params; //List of parameters from another trace source

/*
 * Constructor that converts/stores the pairs of <field name, field type>
 * in the 'fields' member.
*/
TraceSourceContext(const char* tname,
                    vector<pair<string, ValueTypes>> fields_def) {
    name = tname;
    string key;
    // Referenced by field name => field type
    for (size_t i=0; i < fields_def.size(); ++ i) {
        key = fields_def[i].first;
        fields[key].t = fields_def[i].second;
    }
}

/*
 * Generic Callback that can be used by derived objects. It fills the
 * 'value' member in the 'fields' structure with a void* to the value
 * retrieved from the component.
*/
template <class T>
static T *TraceCallback(void* user_data,
                         const MTI::EventClass *event_class,
                         const MTI::EventRecord *record) {
    T *tc = static_cast<T*>(user_data);
    // Filled by Component
    TraceFieldsMap::iterator it;
    for (it = tc->fields.begin(); it != tc->fields.end(); ++it) {
       // Based in the type creates an object with initial
       // value retrieved from the component using the index
       // for that field.
        switch (it->second.t) {
            case u32: it->second.value = new uint32_t(
                record->Get<uint32_t>(event_class, it->second.index));
                break;
            case boolT: it->second.value = new bool(
                record->GetBool(event_class, it->second.index));
                break;
            case u8: it->second.value = new uint8_t(
                record->Get<uint8_t>(event_class, it->second.index));
                break;
        }
    }
    return tc;
}

/*
 * Generic method to copy the fields from this trace source to the params
 * member in other trace source. Optionally a list of field names can be
 * passed to filter the list of field names copied.
 * The params member is a Map of with the Field Id (name)  as the key.
*/
void PassFieldstoParams(TraceSourceContext *target,
                            vector<string> field_names={}) {
        TraceFieldsMap::iterator it;
        for (it = fields.begin(); it != fields.end(); ++it) {
            bool found = std::find(field_names.begin(), field_names.end(),
                it->first) != field_names.end();
            if ((!field_names.empty()) && (!found))
                continue;
            target->params[it->first].t = it->second.t;
            switch (it->second.t) {
                case u32:
                    target->params[it->first].value =
                        new uint32_t(*((uint32_t*)it->second.value));
                    break;
                case boolT:
                    target->params[it->first].value =
                        new bool(*((bool*)it->second.value));
                    break;
                case u8:
                    target->params[it->first].value =
                        new uint8_t(*((uint8_t*)it->second.value));
                    break;
            }
        }
}
/*
 * Method that creates an event object in the trace source based in the
 * fields given in the constructor. It then registers the given callback
 * to this event.
*/
MTI::EventClass *CreateEvent(ComponentTraceInterface **ptr_cti,
                MTI::CallbackT callback) {

    ComponentTraceInterface *cti = *ptr_cti;
    std::stringstream ss;
    ComponentTraceInterface *mti = 0;

    if (cti->GetTraceSource(name.c_str()) != 0) {
        TraceSource* ts = cti->GetTraceSource(name.c_str());
        printf("Trace source attached: %s\n", ts->GetName());

        size_t map_size = fields.size();
        ValueBind_t *values_array = new ValueBind_t[map_size + 1];
        TraceFieldsMap::iterator it;
        int i = 0;
        for (it = fields.begin(); it != fields.end(); ++it) {
            values_array[i]= ((ValueBind_t) { it->first.c_str(),
                &it->second.index });
            ++i;
        };
        values_array[map_size] = {0, 0}; //sentinel

        mti = static_cast<ModelTraceInterface *>(cti);
        if (!RegisterCallbackForComponent(mti, name.c_str(), values_array,
            this, callback, &event_class, ss)) {
            Error(ss.str().c_str());
            return 0;
        }
        return event_class;
    }
    return 0;
}
};

/*
 * Class and types used to handle trace sources belonging to a
 * component.
*/
typedef map<string, TraceSourceContext*> MapTraceSourcesType;
class TraceComponentContext {
    public:
        string trace_path;
        MapTraceSourcesType trace_sources;

TraceComponentContext(string tpath) {
        trace_path = tpath;
}

void AddTraceSource(TraceSourceContext *ts) {
        trace_sources[ts->name] = ts;
}
};

/*
 * Class used to instantiate a Instruction trace source
*/
class InstructionTraceContext: public TraceSourceContext {
    public:
        using TraceSourceContext::TraceSourceContext;
        InstStatMap stats;
        uint64_t nb_insts;

    static void Callback(void* user_data,
                         const MTI::EventClass *event_class,
                         const MTI::EventRecord *record) {
        InstructionTraceContext* itc = static_cast<InstructionTraceContext*>
                                       (user_data);
        itc->nb_insts++; // Number of instructions
        // Filled by Component
        uint32_t pc = record->GetAs<uint32_t>(event_class,
                                                      itc->fields["PC"].index);
        uint32_t size = record->Get<uint32_t>(event_class,
                                                    itc->fields["SIZE"].index);
        // Save PC stats. If not already present in the map, a counter with
        // value 0 will be created before incrementing.
        InstStat& is = itc->stats[pc];
        is.cnt++;
        is.size = size;
    };
};

struct mode_change_type {
    uint8_t mode_value;
    char name[5];
};
const struct mode_change_type types[] = {
    {0x0 , "EL0t"}, //0
    {0x4 , "EL1t"}, //1
    {0x5 , "EL1h"}, //2
    {0x8 , "EL2t"}, //3
    {0x9 , "EL2h"}, //4
    {0xc , "EL3t"}, //5
    {0xd , "EL3h"}, //6
    {0x10 , "usr"}, //7
    {0x11 , "fiq"}, //8
    {0x12 , "irq"}, //9
    {0x13 , "svc"}, //10
    {0x16 , "mon"}, //11
    {0x17 , "abt"}, //12
    {0x1a , "hyp"}, //13
    {0x1b , "und"}, //14
    {0x1f , "sys"},  //15
    /* Secure modes */
    {0x0 , "EL0t"}, //16
    {0x4 , "EL1t"}, //17
    {0x5 , "EL1h"}, //18
    {0x8 , "EL2t"}, //19
    {0x9 , "EL2h"}, //20
    {0xc , "EL3t"}, //21
    {0xd , "EL3h"}, //22
    {0x10 , "usr"}, //23
    {0x11 , "fiq"}, //24
    {0x12 , "irq"}, //25
    {0x13 , "svc"}, //26
    {0x16 , "mon"}, //27
    {0x17 , "abt"}, //28
    {0x1a , "hyp"}, //29
    {0x1b , "und"}, //30
    {0x1f , "sys"}  //31
};

class ModeChangeTraceContext: public TraceSourceContext {
    public:
        using TraceSourceContext::TraceSourceContext;
        MTI::EventClass *event;
        uint32_t mode_mask;
        InstructionTraceContext* itc;


        static void Callback(void* user_data,
                             const MTI::EventClass *event_class,
                             const MTI::EventRecord *record)
        {
            ModeChangeTraceContext* mtc = static_cast<ModeChangeTraceContext*>
                (user_data);
            static bool trace = false;
            bool new_trace = false;
            uint8_t mode = record->GetAs<char>(event_class,
                    mtc->fields["MODE"].index);
            uint8_t nsecure = record->Get<char>(event_class,
                    mtc->fields["NON_SECURE"].index);
            int start_mask  = 0;

            if(nsecure) {
                start_mask = 0;
            } else {
                start_mask = 16;
            }

            for (int i = start_mask; i < start_mask + 16; i++) {
                if (types[i].mode_value == mode) {
                    new_trace = new_trace || (mtc->mode_mask & (1 << i));
                    break;
                }
            }

            if (new_trace && !trace) {
                mtc->event->RegisterCallback(InstructionTraceContext::Callback,
                                             mtc->itc);
            } else if (!new_trace && trace){
                mtc->event->UnregisterCallback(
                        InstructionTraceContext::Callback,
                        mtc->itc);
            }
            trace = new_trace;
        };

};
#endif // _COVERAGE_TOOL_COVERAGE_PLUGIN_TRACE_SOURCES_H_
