/* --COPYRIGHT--,EPL
 *  Copyright (c) 2008-2020 Texas Instruments Incorporated
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *      Texas Instruments - initial implementation
 *
 * --/COPYRIGHT--*/

/*
 *  ======== StateReader ========
 *  These APIs are all designed so that they will not re-read data that has
 *  already been read in.
 */

/* global xdc, Program, $addr */

var symTable;
var strDec;

/*
 *  ======== instance$meta$init ========
 */
function instance$meta$init(inSymTable, inStrDec)
{
    symTable = inSymTable;
    strDec = inStrDec;
}

/*
 *  ======== fetchModuleState ========
 *  Scans the given module's module state structure. If the structure has
 *  already been scanned, this function returns immediately.
 */
function fetchModuleState(mod)
{
    /* Return if the object has already been scanned. */
    if (mod.state) {
        return;
    }

    /* If the module does not have module state, return null. */
    if (!('Module_State' in mod.useMod)) {
        mod.state = null;
        mod.addr = "N/A";
        return;
    }

    /* Look up the Module state structure and fetch it. */
    mod.addr = $addr(symTable.getSymbolValue(mod.name.replace(/\./g, '_') +
                                             '_Module__state__V'));
    /* It's not clear yet what are the conditions under which 'Module_State'
     * is found in mod.useMod, but getSymbolValue returns '-1', which means
     * that the symbol wasn't found. This happens on Arm for IAR, for the
     * module Text.
     */
    if (mod.addr == -1 || mod.addr == 0) {
        mod.state = null;
        mod.addr = "N/A";
        return;
    }

    var modState = strDec.fetchStruct(mod.useMod.Module_State,
                                      Number(mod.addr), true);

    /* Bind the state structure to the module as the state field */
    mod.state = modState;
}

/*
 *  ======== fetchAllInstStates ========
 *  This function makes sure that all of the instance state structures for
 *  this module have been scanned in. It does not call any view$init functions.
 */
function fetchAllInstStates(mod)
{
    /* Retrieves the addresses of all of the instance state structures. */
    fetchAllInstAddrs(mod);

    /* Fetch all of the static instance states. */
    for (var i = 0; i < mod.staticInstAddrs.length; i++) {
        fetchInstState(mod, mod.staticInstAddrs[i], i);
    }

    /* Fetch all of the dynamic instance states. */
    for (var i = 0; i < mod.dynInstAddrs.length; i++) {
        fetchInstState(mod, mod.dynInstAddrs[i], -1);
    }
}

/*
 *  ======== fetchAllInstAddrs ========
 *  Retrieves the addresses of all of the statically and dynamically created
 *  instances. These will be placed in mod.staticInstAddrs and
 *  mod.dynInstAddrs.
 *
 *  TODO - fetchInstState had a check for null address for when there are no
 *         instances.
 *         Make sure this never adds "null" as an address.
 */
function fetchAllInstAddrs(mod)
{
    /* TODO - staticInstAddrs should be constant? But clear cache deletes
     *  mod, so this won't preserve them.
     */
    /* Check if they have already been retrieved. */
    if (mod.readAllAddrs) {
        return;
    }

    var Types = xdc.module('xdc.runtime.Types');

    /* Create an array of the addresses of all of the static instances. */
    mod.staticInstAddrs = new Array();

    /* Determine the number of instance objects from the config. */
    var numInsts = mod.cfg.$instances.length;

    /* If there are static instances, compute their addresses. */
    if (numInsts != 0) {
        /* Retrieve the static instance addresses, which are in an array. */
        var instArrSym = mod.name.replace(/\./g, '_') + '_Object__table__V';
        var instArrAddr = symTable.getSymbolValue(instArrSym);

        if (instArrAddr == -1) {
            xdc.module("xdc.rov.runtime.Monitor").println("There are "
                + mod.name + " static instances in the app configuration, but "
                + "ROV could not find them in the app executable (required "
                + "symbol '" + instArrSym + "' is missing). The instances "
                + "might have been removed by the linker because they weren't "
                + "referenced.");
        }
        else {
            /* Determine the number and size of the instance objects
             * from the config */
            var instSize = mod.useMod.Instance_State.$sizeof();

            /* Add the address of each of the static instances. */
            for (var i = 0; i < numInsts; i++) {
                mod.staticInstAddrs.$add(instArrAddr + (i * instSize));
            }
        }
    }

    /* Create an array of the addresses of all of the dynamic instances. A
     * JavaScript array is used initially, so we can sort instances by address.
     */
    var tempArray = [];
    /* Add all of the dynamically constructed instances. */
    if ('$constructInst' in Program) {
        var modStructType = mod.name.replace(/\./g,'_') + "_Struct";
        for each (var constructInst in Program.$constructInst) {
            if (modStructType == constructInst.type) {
                var symbolname = constructInst.name;
                if (symbolname.indexOf('.') != -1) {
                    symbolname = symbolname.substring(0,
                        symbolname.indexOf('.'));
                }
                if ("addr" in constructInst && constructInst.addr != null) {
                    tempArray.push(parseInt(constructInst.addr));
                }
                else {
                    var constructInstAddr = symTable.getSymbolValue(symbolname);
                    if (constructInstAddr != -1) {
                        if ("offset" in constructInst) {
                            constructInstAddr += constructInst.offset;
                        }
                        tempArray.push(constructInstAddr);
                    }
                }
            }
        }
        tempArray.sort();
        mod.dynInstAddrs = tempArray;
    }

    /* Check the module's memory policy. */
    if (String(mod.cfg.common$.memoryPolicy) == String(Types.STATIC_POLICY)) {
        mod.readAllAddrs = true;
        return;
    }

    /* Retrieve the module's linked list of dynamic instances. */
    var modLinkSym = mod.name.replace(/\./g, '_') + '_Module__root__V';
    var modLinkAddr = symTable.getSymbolValue(modLinkSym);

    /* Check if the symbol was found */
    if (modLinkAddr != -1 && modLinkAddr != 0) {
        try {
            var modLink = strDec.fetchStruct(Types.Link, Number(modLinkAddr),
                                             true);

            /*
             * Create a temporary map of the addresses discovered to use for
             * detecting loops in the linked list.
             */
            var addrs = {};

            /*
             * The module header is also part of a linked list of all of the
             * dynamically created instances.
             */
            var instHdrAddr = modLink.next;

            /* Loop over the list. */
            while (instHdrAddr != modLinkAddr) {

                /* Add the header address to the temporary map. */
                addrs[instHdrAddr] = true;

                /* The instance address is offset from the header. */
                var instAddr = Number(instHdrAddr) + Types.InstHdr.$sizeof();

                /* Add the instance's address. */
                mod.dynInstAddrs.$add(instAddr);

                /*
                 * Get the actual header struct and find the address of the
                 * next header struct.
                 */
                var instHdr = strDec.fetchStruct(Types.InstHdr,
                                                 Number(instHdrAddr), true);

                /* Get the address of the next instance header. */
                instHdrAddr = instHdr.link.next;

                // If we've detected a loop in the instance queue throw an error
                if (instHdrAddr in addrs) {
                    throw (new Error(
                        "Detected loop in instance queue at address "
                        + instHdrAddr));
                }
            }
        }
        catch (e) {
            Program.debugPrint("xdc.rov.decoder: Cannot read the list of "
                + "dynamic instances.");
        }
    }

    mod.readAllAddrs = true;
}

/*
 *  ======== getKey ========
 *  Makes a key out of the instance's address for the module's instMap.
 */
function getKey(addr)
{
    return ('0x' + Number(addr).toString(16));
}

/*
 *  ======== fetchInstState ========
 *  This function scans in a single instance's state, and associates various
 *  metadata (used by the view$init functions) with the instance object.
 *  Returns the inst object for Program.scanHandle.
 *  This API is responsible for caching the retrieved instance states. If the
 *  instance state at the given address has already been read in, it will not
 *  be read again.
 */
function fetchInstState(mod, instAddr, staticIndex)
{
    /*
     * Check to see if this instance has already been scanned.
     * Instances may be discovered through Program.scanInstanceView, or a call
     * to Program.scanHandle from a different module's view init code; so it's
     * possible that the instance has already been scanned.
     */
    var key = getKey(instAddr);
    if ((mod.instMap) && (key in mod.instMap)) {
        return (mod.instMap[key]);
    }

    /*
     * If this module's instance state structure has a size field, fetch the
     * instance state structure.
     */
    var obj;
    if ('$sizeof' in mod.useMod.Instance_State) {
        obj = strDec.fetchStruct(mod.useMod.Instance_State,
                                 Number(instAddr), true);
    }
    /* Otherwise, this module has no real instance state (such as GateHwi). */
    else {
        /* TODO - Is this all right? Maybe call fetchStruct anyway? */
        Program.debugPrint("xdc.rov.decoder:"
            + " Module does not have instance state.");
        var temp = new mod.useMod.Instance_State;
        obj = {};

        obj.$addr = $addr(instAddr);
        obj.$type = temp.$type;
    }

    /* Create an instance descriptor for the instance. */
    var inst = getInstDesc(mod, obj, staticIndex);

    /* Return the inst for scanHandle */
    return (inst);
}

/*
 *  ======== getInstDesc ========
 *  Takes a decoded state structure and creates an ROVInstanceDesc for it.
 *  Also retrieves the label for the instance.
 */
function getInstDesc(mod, obj, staticIndex)
{
    /*
     * The instMap will map instance addresses to instance objects.
     * It may already be present from a call to Program.scanHandle in a
     * different module's view init code.
     */
    if (!mod.instMap) {
        mod.instMap = new Object();
    }

    /* Return immediately if this object has already been scanned. */
    var key = getKey(obj.$addr);
    if (key in mod.instMap) {
        return (mod.instMap[key]);
    }

    /* Create a new instance descriptor to represent the instance */
    var inst = new Program.ROVInstanceDesc;

    /* Store the state structure and its address. */
    inst.state = obj;
    inst.addr = obj.$addr;

    /* Get the instance's label */
    obj.$label = getLabel(mod, obj, staticIndex);

    /* Add the instance to the module's list. */
    mod.instances.$add(inst);

    /*
     * Add the instance to the map, so we can quickly check if it's
     * already been scanned.
     */
    mod.instMap[key] = inst;

    return (inst);
}

/*
 * ======== getLabel ========
 * Helper function called from getInstLabel to retrieve the label for the
 * given instance.
 */
function getLabel(mod, obj, staticIndex)
{
    /* Create the label for the instance. */
    var label = mod.name + "@" + Number(obj.$addr).toString(16);

    /* If this is a static instance, get the instance name from the capsule. */
    var givenName;
    if (staticIndex != -1) {
        givenName =
            Program.$modules[mod.name].$instances[staticIndex].instance.name;
        if (givenName != null) {
            label += (":" + givenName);
            return (label);
        }
    }
    /* Otherwise, if this is a dynamically created instance,
     * check if it has a name. */
    else if ('__name' in obj) {
        /* If the __name field is null, no name was given. */
        if (Number(obj.__name) != 0) {
            try {
                givenName =
                    xdc.module('xdc.runtime.Text').fetchAddr(Number(obj.__name));
            }
            catch (e) {
                if (e.message == "abort") {
                    throw (e);
                }
                /*
                 * Need a way to report error to user. Just display
                 * error instead of name.
                 */
                givenName = "Error retrieving given name at 0x" +
                            Number(obj.__name).toString(16) + ": " +
                            e.toString();
            }
            label += ":" + givenName;
            return (label);
        }
    }

    return (label);
}

/*
 *  ======== fetchHandleState ========
 *  The fetchInstState API needs to know whether the given instance
 *  is static or dynamic. If we just have a handle to an instance, we first
 *  need to determine whether it is static or dynamic.
 */
function fetchHandleState(mod, instAddr)
{
    /*
     * Check if this is a static instance. If it is, we need to find its index
     * in the module header instance array so the decoder can retrieve the
     * instance name from the recap file.
     */
    fetchAllInstAddrs(mod);

    var staticIndex = -1;
    for (var i = 0; i < mod.staticInstAddrs.length; i++) {
        if (Number(instAddr) == Number(mod.staticInstAddrs[i])) {
            staticIndex = i;
            break;
        }
    }

    /* Fetch this individual instance's state, adding it to the module. */
    var inst = fetchInstState(mod, instAddr, staticIndex);

    return (inst);
}
