///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB                               //
//                                                                           //
// All rights reserved. This program and the accompanying materials          //
// are made available under the terms of the Eclipse Public License v2.0     //
// which accompanies this distribution, and is available at                  //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                 //
///////////////////////////////////////////////////////////////////////////////
function Model(p_dataGenerator) {

    var PATTERN = /%Parent(\d+)%/g;

    var dataGenerator = p_dataGenerator;
    var model = {};

    /**
        Finds an element in the given section of the Help.
        NOTE: this is a recursive function, since it is possible that the element is not in the root of the section.
        @param element: the element
        @param list: the section in the Help we will search
    */
    function findElementType(element, list) {
        var type;
        var listLength = list.length;
        for (var j = 0; j < listLength; ++j) {
            var dataElement = list[j].dataElement;
            if (dataElement.name == element) {
                type = dataElement.valueType;
            }
            if (list[j].children != undefined && type == undefined) {
                type = findElementType(element, list[j].children);
            }
        }
        return type;
    }

    /**
        Finds the valueType of a source and element pair using the Help.
        @param source: the data source
        @param element: the name of a data element
        @returns the type or null if the pair is not in the Help
    */
    function getType(source, element) {
        var type;
        var sourcesLength = DSHelp.sources.length;
        for (var i = 0; i < sourcesLength; ++i) {
            var obj = DSHelp.sources[i];
            if (obj.source == source) {
                type = findElementType(element, obj.dataElements);
            }
        }
        
        if (type == undefined) {
            mlog("Not found in HELP, using intType:" + " source: " + source + " dataElement: " + element);
            return "intType";
        } else {
            return type;
        }
    }
    
    function replaceParent(str, parents) {
        var pattern = new RegExp(PATTERN);
        var match = pattern.exec(str);
        return parents[parseInt(match[1])].val;
    }

    /**
        The key of the content in the hashmap is a concatenation of its source, element and parameters so we have to sort the parameters.
        @param data: a getData object
        @param parents: the list of parents
        @returns the key
    */
    function getGetDataKey(data, parents) {
        var list = [];
        if (data.params != undefined) {
            for (var i = 0; i < data.params.length; ++i) {
                var paramValue = data.params[i].paramValue;
                list.push(paramValue.replace(new RegExp(PATTERN), function(match) {return replaceParent(match, parents)}));
            }
        }
        list.sort();
        
        var key = data.source + "." + data.element;
        for (var i = 0; i < list.length; ++i) {
            key += "." + list[i];
        }
        
        return key;
    }

    /**
        The key of the content in the hashmap is a concatenation of its source, element and parameters so we have to sort the parameters.
        @param: data a getData object
        @returns the key
    */
    function getSetDataKey(data) {
        var list = [];
        if (data.params != undefined) {
            for (var i = 0; i < data.params.length; ++i) {
                list.push(data.params[i].paramValue);
            }
        }
        list.sort();
        
        var key = data.source + "." + data.element;
        for (var i = 0; i < list.length; ++i) {
            key += "." + list[i];
        }
        
        return key;
    }

    /**
        This function creates random content for the current node that belongs to the data and parents.
        If the content was already generated, we simply return it.
        @param data: a getData object
        @param parents: the parent list of the current node
        @returns the node or the list of nodes
    */
    this.getContent = function(data, parents) {
        var key = getGetDataKey(data, parents);
        if (model[key] == undefined) {
            model[key] = dataGenerator.generateContent(data.source, data.element, getType(data.source, data.element));
        }
        return model[key];
    };

    /**
        This function sets the content of a node.
        @oaram data: a setData object
        @returns the node or the list of nodes that was or were changes
    */
    this.setContent = function(data) {
        var key = getSetDataKey(data);
        var content = model[key] || {"node": {"val": "Value cannot be changed", "tp": 4}};
        if (data.tp && (data.tp < 0 || data.tp > 11))
            if (data.tp === content.node.tp)
                return {"node": {"val": "Value cannot be changed", "tp": 4}};
            else
                return {"node": {"val": "Invalid tp: " + data.tp, "tp": 4}};
        if (content.list && data.indxsInList.length == 1) {
            content.list[data.indxsInList[0]].node.val = data.content;
            content.list[data.indxsInList[0]].node.tp = data.tp;
        } else {
            content.node.val = data.content;
            content.node.tp = data.tp;
        }
        return content;
    };

    /**
        This functions adds a new node using a setData object and a tp number.
        @param key: the key in the hashmap
        @param content: the content
    */
    this.addContent = function(key, content) {
        model[key] = content;
    }
}