///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2000-2017 Ericsson Telecom AB                               //
//                                                                           //
// 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                                 //
///////////////////////////////////////////////////////////////////////////////
function TestConfigModelFiller(p_model) {

    /** private member */
    var model;

    /** contructor */
    model = p_model;

    /** private functions */

    function getKey(source, element, parents) {
        var key = source + "." + element;
        parents.sort();
        for (var i = 0; i < parents.length; ++i) {
            key += "." + parents[i];
        }
        return key;
    }

    /**
        Traverse a list in the data. Creates the content by collecting the answers in a list.
    */
    function traverseModelList(source, element, parents, data) {
        var content = {list : []};
        for (var i = 0; i < data.length; ++i) {
            var obj = data[i];
            var ans = traverseModelObject(source, parents, obj);
            content.list.push(ans);
        }
        model.addContent(getKey(source, element, parents), content);
        
    }

    /**
        Traverses an object in the data. Creates a node content and traverses its list or object elements recursively.
    */
    function traverseModelObject(source, parents, data) {
        var content = {node : {}};
        var value = data["Value"];
        content.node.val = value;
        content.node.tp = data["tp"];
        for (var key in data) {
            if (data.hasOwnProperty(key) && key != "Value" && key != "tp") {
                parents.push(value);
                if (data[key]["Value"] == undefined) {
                    traverseModelList(source, key, parents, data[key]);
                } else {
                    model.addContent(getKey(source, key, parents), traverseModelObject(source, parents, data[key]));
                }
                parents.pop();
            }
        }
        return content;
    }

    /** public functions */

    this.fillModel = function(data) {
        var source = data["DSClientName"];
        for (var key in data) {
            if (key == "DSClientName" || !data.hasOwnProperty(key)) {
                continue;
            }
            var parents = [];
            traverseModelList(source, key, parents, data[key]);
        }
    }
}