// 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 DSHelpToRequest_manual() {
    "use strict";
    var PATTERN = /%Parent(\d+)%/g;
    var PATTERN_IDX = /%Parent(\d+)::idx%/g;

    var v_help;
    var v_fullRequest;
    var v_this = this;

    this.setHelp = function(p_help) {
        v_help = p_help;
    };

    this.setRequest = function(p_request) {
        v_fullRequest = p_request;
    };

    ///////////////////// UTILITIES, ADDING AND CREATING REQUESTS //////////////////////////////

    this.createEmptyRequest = function(p_pos) {
        var request = {
            "getData" : {
                "source" : "Source",
                "element" : "Element"
            }
        };
        requestCreated(request, p_pos);
        return request;
    };

    this.createRequest = function(p_helpPath, p_pos) {
        var request = generateGetData(p_helpPath, []);
        requestCreated(request, p_pos);
        return request;
    };

    function requestCreated(p_request, p_pos) {
        if (p_pos == undefined) {
            p_pos = v_fullRequest.length;
        }

        v_fullRequest.splice(p_pos, 0, p_request);
    }

    this.addEmptyChildRequest = function(p_requestPath, p_pos) {
        var childRequest = {
            "getData" : {
                "source" : "Source",
                "element" : "Element"
            }
        };
        childRequestCreated(childRequest, p_requestPath, p_pos);
        return childRequest;
    };

    this.addChildRequest = function(p_helpPath, p_requestPath, p_pos, p_setData) {
        if (!doesNotHaveGetDataOnPath(p_requestPath)) {
            var childRequest = generateGetData(p_helpPath, p_requestPath);

            if (p_setData) {
                childRequest.setData = childRequest.getData;
                childRequest.getData = undefined;
                addContentAndTpToSetData(childRequest.setData, getHelpDataElement(p_helpPath).dataElement.dataElement);
            }

            childRequestCreated(childRequest, p_requestPath, p_pos);
            return childRequest;
        }
    };

    function addContentAndTpToSetData(setData, helpElement) {
        if (helpElement.valueType == "intType") {
            setData.content = "0";
            setData.tp = 1;
        } else if (helpElement.valueType == "floatType") {
            setData.content = "0.0";
            setData.tp = 2;
        } else if (helpElement.valueType == "boolType") {
            setData.content = "true";
            setData.tp = 3;
        } else if (helpElement.valueType == "charstringType") {
            setData.content = "";
            setData.tp = 4;
        } else if (helpElement.valueType == "octetstringType") {
            setData.content = "";
            setData.tp = 5;
        } else if (helpElement.valueType == "hexstringType") {
            setData.content = "";
            setData.tp = 6;
        } else if (helpElement.valueType == "bitstringType") {
            setData.content = "";
            setData.tp = 7;
        } else if (helpElement.valueType == "integerlistType") {
            setData.content = "0";
            setData.tp = 8;
            setData.indxsInList = [0];
        } else if (helpElement.valueType == "floatlistType") {
            setData.content = "0.0";
            setData.tp = 9;
            setData.indxsInList = [0];
        } else if (helpElement.valueType == "charstringlistType") {
            setData.content = "";
            setData.tp = 10;
            setData.indxsInList = [0];
        } else if (helpElement.valueType == "statusLEDType") {
            setData.content = "[led:green]Ok";
            setData.tp = 11;
        } else {
            setData.content = "";
            setData.tp = 0;
        }
    }

    this.copyRequest = function(p_path) {
        var currentRq = v_this.getRequestFromPath(p_path);
        var setOrGetData = getOrSetData(currentRq);
        var requestToCopy = {};
        requestToCopy[setOrGetData] = mcopy(v_this.getRequestCopy(p_path));
        var position = p_path.pop();
        ++position;
        if (p_path.length != 0) {
            var parent = v_this.getRequestFromPath(p_path);
            parent = parent[getOrSetData(parent)];
            parent.children.splice(position, 0, requestToCopy);
        } else {
            v_fullRequest.splice(position, 0, requestToCopy);
        }
        return requestToCopy;
    };

    this.getRequestCopy = function(p_path) {
        var original = v_this.getRequestFromPath(p_path);
        original = original[getOrSetData(original)];
        var copy = mcopy(original);
        delete copy.children;
        return copy;
    };

    function childRequestCreated(p_childRequest, p_requestPath, p_pos) {
        var request = v_this.getRequestFromPath(p_requestPath);
        request = request[getOrSetData(request)];
        if (request.children == undefined) {
            request.children = [];
        }

        if (p_pos == undefined) {
            p_pos = request.children.length;
        }

        if (request.ptcname != undefined) {
            p_childRequest.getData.ptcname = request.ptcname;
        }

        request.children.splice(p_pos, 0, p_childRequest);
    }

    this.deleteRequest = function(p_requestPath) {
        var toDeleteIndex = p_requestPath.pop();
        var parent = this.getRequestFromPath(p_requestPath);
        if (parent == undefined) {
            v_fullRequest.splice(toDeleteIndex, 1);
        } else {
            var setOrGetData = getOrSetData(parent);
            parent[setOrGetData].children.splice(toDeleteIndex, 1);
        }
    };

    this.convertToSetData = function(p_path) {
        var request = this.getRequestFromPath(p_path);
        request.setData = request.getData;
        request.getData = undefined;
        request.setData.children = undefined;
        request.setData.selection = undefined;
        request.setData.filter = undefined;
        request.setData.rangeFilter = undefined;
        request.setData.writableInfo = undefined;
        request.setData.timeline = undefined;
        request.setData.content = "";
        request.setData.tp = 0;
    };

    this.convertToGetData = function(p_path) {
        var request = this.getRequestFromPath(p_path);
        request.getData = request.setData;
        request.setData = undefined;
        request.getData.content = undefined;
        request.getData.tp = undefined;
    };

    this.getRequest = function() {
        return v_fullRequest;
    };

    this.getRequestFromPath = function(p_path) {
        var request = v_fullRequest[p_path[0]];
        for (var i = 1; i < p_path.length; ++i) {
            request = request[getOrSetData(request)].children[p_path[i]];
        }
        return request;
    };

    function getHelpDataElement(p_helpPath) {
        var source = v_help.sources[p_helpPath[0]];
        var dataElement = source.dataElements[p_helpPath[1]];
        for (var i = 2; i < p_helpPath.length; ++i) {
            dataElement = dataElement.children[p_helpPath[i]];
        }
        return {
            "source" : source,
            "dataElement" : dataElement
        };
    }

    function generateGetData(p_helpPath, p_requestPath, p_filtersThatCanBeParams) {
        var element = getHelpDataElement(p_helpPath);
        var getData = {
            "getData" : {
                "source" : element.source.source,
                "element" : element.dataElement.dataElement.name,
                "params" : getParamsForRequest(p_helpPath, p_requestPath, p_filtersThatCanBeParams)
            }
        };
        return getData;
    }

    ///////////////////// FILTERS //////////////////////////////

    this.getFilterPart = function(p_requestPath, p_filterPath) {
        var request = v_this.getRequestFromPath(p_requestPath);
        var filter;
        if (request.getData)
            filter = request.getData.filter;
        else
            filter = request.setData.filter;
        if (p_filterPath.length == 0) {
            return filter;
        } else {
            var i = 0;
            while (i < p_filterPath.length - 1) {
                if (filter.request.params == undefined || filter.request.params[p_filterPath[i]] == undefined) {
                    filter = filter.request.remapTo;
                } else {
                    filter = filter.request.params[p_filterPath[i]].paramValue;
                }
                ++i;
            }
            if (filter.request.params == undefined || filter.request.params[p_filterPath[i]] == undefined) {
                return filter.request.remapTo;
            } else {
                return filter.request.params[p_filterPath[i]].paramValue;
            }
        }
    };

    this.getFilterPartCopy = function(p_requestPath, p_filterPath) {
        var filter = mcopy(v_this.getFilterPart(p_requestPath, p_filterPath));
        if (filter.request != undefined) {
            delete filter.request.params;
            delete filter.request.remapTo;
        }
        return filter;
    };

    function changeFilterPart(p_requestPath, p_filterPath, p_changeTo, p_paramName, p_change) {
        var request = v_this.getRequestFromPath(p_requestPath);
        var filtercontainer;
        if (request.getData)
            filtercontainer = request.getData;
        else
            filtercontainer = request.setData;
        if (p_filterPath.length == 0) {
            filtercontainer.filter = p_changeTo;
        } else {
            var filter = filtercontainer.filter;
            var i = 0;
            while (i < p_filterPath.length - 1) {
                if (filter.request.params == undefined || filter.request.params[p_filterPath[i]] == undefined) {
                    filter = filter.request.remapTo;
                } else {
                    filter = filter.request.params[p_filterPath[i]].paramValue;
                }
                ++i;
            }
            if (p_paramName == "remapTo" || (p_change && (filter.request.params == undefined || filter.request.params[p_filterPath[i]] == undefined))) {
                filter.request.remapTo = p_changeTo;
            } else {
                if (filter.request.params == undefined) {
                    filter.request.params = [];
                }
                if (filter.request.params[p_filterPath[i]] == undefined) {
                    filter.request.params[p_filterPath[i]] = {};
                }
                if (p_paramName != undefined) {
                    filter.request.params[p_filterPath[i]].paramName = p_paramName;
                }
                filter.request.params[p_filterPath[i]].paramValue = p_changeTo;
            }
        }
    }

    function deleteFilterPart(p_requestPath, p_filterPath) {
        var request = v_this.getRequestFromPath(p_requestPath);
        var filtercontainer;
        if (request.getData)
            filtercontainer = request.getData;
        else
            filtercontainer = request.setData;
        if (p_filterPath.length == 0) {
            filtercontainer.filter = undefined;
        } else {
            var filter = filtercontainer.filter;
            var i = 0;
            while (i < p_filterPath.length - 1) {
                if (filter.request.params == undefined || filter.request.params[p_filterPath[i]] == undefined) {
                    filter = filter.request.remapTo;
                } else {
                    filter = filter.request.params[p_filterPath[i]].paramValue;
                }
                ++i;
            }
            if (filter.request.params == undefined || filter.request.params[p_filterPath[i]] == undefined) {
                filter.request.remapTo = undefined;
            } else {
                filter.request.params.splice(p_filterPath[i], 1);
            }
        }
    }

    this.addFilterPart = function(p_requestPath, p_filterPath, p_paramName) {
        changeFilterPart(p_requestPath, p_filterPath, {"dataValue": "true"}, p_paramName, false);
    };

    this.deleteFilterPart = function(p_requestPath, p_filterPath) {
        deleteFilterPart(p_requestPath, p_filterPath);
    };

    this.changeParamNameOfFilterRequest = function(p_requestPath, p_filterPath, p_paramName) {
        var changeTo = v_this.getFilterPart(p_requestPath, p_filterPath);
        changeFilterPart(p_requestPath, p_filterPath, changeTo, p_paramName, true);
    };

    this.convertFilterPartToRequest = function(p_requestPath, p_filterPath, p_helpPath) {
        var filterRequest = generateGetData(p_helpPath, p_requestPath, getFiltersThatCanParams(p_requestPath, p_filterPath)).getData;
        if (filterRequest.params != undefined) {
            for (var i = 0; i < filterRequest.params.length; ++i) {
                filterRequest.params[i].paramValue = {"dataValue": filterRequest.params[i].paramValue};
            }
        }

        changeFilterPart(p_requestPath, p_filterPath, {"request": filterRequest}, undefined, true);
    };

    this.convertFilterPartToDataValue = function(p_requestPath, p_filterPath, p_newValue) {
        changeFilterPart(p_requestPath, p_filterPath, {"dataValue": p_newValue}, undefined, true);
    };

    function getFiltersThatCanParams(p_requestPath, p_filterPath) {
        var filters = [];
        var filterrq = v_this.getRequestFromPath(p_requestPath);
        var filter = filterrq[getOrSetData(filterrq)].filter;
        if (p_filterPath.length > 0) {
            for (var i = 0; i < p_filterPath.length - 1; ++i) {
                if (filter.request.params == undefined || filter.request.params[p_filterPath[i]] == undefined) {
                    filters.push({'getData': filter.request});
                    filter = filter.request.remapTo;
                } else {
                    filters.push(undefined);
                    filter = filter.request.params[p_filterPath[i]].paramValue;
                }
            }
        }
        return filters;
    }

    this.isValidToConvertFilterToRequest = function(p_requestPath, p_filterPath, p_helpPath) {
        return p_helpPath.length > 1 && v_this.getFilterPart(p_requestPath, p_filterPath).request == undefined && checkIfAllReferencesFound(getParamsForRequest(p_helpPath, p_requestPath, getFiltersThatCanParams(p_requestPath, p_filterPath)));
    };

    this.isValidToAddParamToFilterRequest = function(p_requestPath, p_filterPath) {
        var filterPathCopy = mcopy(p_filterPath);
        filterPathCopy.pop();
        if (v_this.getFilterPart(p_requestPath, filterPathCopy).request != undefined) {
            return true;
        } else {
            return false;
        }
    };

    ///////////////////// VALIDATION AND PARAMETER SEARCHING //////////////////////////////

    function doesNotHaveGetDataOnPath(p_requestPath) {
        if (p_requestPath.length == 0) {
            return false;
        }
        var request = v_fullRequest[p_requestPath[0]];
        if (request.getData == undefined) {
            return true;
        }
        for (var i = 1; i < p_requestPath.length; ++i) {
            request = request.getData.children[p_requestPath[i]];
            if (request.getData == undefined) {
                return true;
            }
        }
        return false;
    }

    this.isValidToAddRequest = function(p_helpPath, p_requestPath) {
        if (p_helpPath.length < 2 || p_requestPath.length === 0 || doesNotHaveGetDataOnPath(p_requestPath)) {
            return false;
        } else {
            return checkIfAllReferencesFound(getParamsForRequest(p_helpPath, p_requestPath));
        }
    };

    this.isValidToCreateRequest = function(p_helpPath) {
        if (p_helpPath.length < 2) {
            return false;
        } else {
            var helpParams = getHelpParamsFromPath(p_helpPath);
            if (helpParams == undefined || helpParams.length === 0) {
                return true;
            } else {
                var requestParams = createParamSkeleton(helpParams);
                return checkIfAllReferencesFound(requestParams);
            }
        }
    };

    function getParamsForRequest(p_helpPath, p_requestPath, p_filtersThatCanBeParams) {
        var helpParams = getHelpParamsFromPath(p_helpPath);
        if (helpParams == undefined || helpParams.length === 0) {
            return undefined;
        }

        var requestParams = createParamSkeleton(helpParams);
        if (checkIfAllReferencesFound(requestParams)) {
            return requestParams;
        }

        tarverseHelpBranch(p_helpPath, p_requestPath, requestParams, helpParams, p_filtersThatCanBeParams);
        if (checkIfAllReferencesFound(requestParams)) {
            return requestParams;
        }

        for (var i = 0; i < v_help.sources.length; ++i) {
            traverseFullHelp(v_help.sources[i].dataElements, p_requestPath, requestParams, helpParams, p_filtersThatCanBeParams);
            if (checkIfAllReferencesFound(requestParams)) {
                return requestParams;
            }
        }

        return requestParams;
    }

    function getHelpParamsFromPath(p_helpPath) {
        var element = getHelpDataElement(p_helpPath);
        return element.dataElement.dataElement.parameters;
    }

    function checkIfAllReferencesFound(p_requestParams) {
        if (p_requestParams == undefined) {
            return true;
        }
        for (var i = 0; i < p_requestParams.length; ++i) {
            if (p_requestParams[i].paramValue == undefined) {
                return false;
            }
        }
        return true;
    }

    function createParamSkeleton(p_helpParams) {
        var paramList = [];
        for (var i = 0; i < p_helpParams.length; ++i) {
            var paramName = p_helpParams[i].name;
            var paramValue;
            if (p_helpParams[i].typeDescriptor != undefined && p_helpParams[i].typeDescriptor.reference != undefined) {
                paramList.push({
                    "paramName" : paramName
                });
            } else if (p_helpParams[i].exampleValue != undefined) {
                paramList.push({
                    "paramName" : paramName,
                    "paramValue" : p_helpParams[i].exampleValue
                });
            } else {
                paramList.push({
                    "paramName" : paramName,
                    "paramValue" : ""
                });
            }
        }
        return paramList;
    }

    function tarverseHelpBranch(p_helpPath, p_requestPath, p_requestParams, p_helpParams, p_filtersThatCanBeParams) {
        var source = v_help.sources[p_helpPath[0]];
        var dataElement = source.dataElements[p_helpPath[1]];
        checkDataElementInParams(dataElement, p_requestPath, p_requestParams, p_helpParams, p_filtersThatCanBeParams);

        for (var i = 2; i < p_helpPath.length; ++i) {
            dataElement = dataElement.children[p_helpPath[i]];
            checkDataElementInParams(dataElement, p_requestPath, p_requestParams, p_helpParams, p_filtersThatCanBeParams);
        }
    }

    function traverseFullHelp(p_dataElementList, p_requestPath, p_requestParams, p_helpParams, p_filtersThatCanBeParams) {
        for (var i = 0; i < p_dataElementList.length; ++i) {
            var dataElement = p_dataElementList[i];
            checkDataElementInParams(dataElement, p_requestPath, p_requestParams, p_helpParams, p_filtersThatCanBeParams);
            if (p_dataElementList[i].children != undefined) {
                traverseFullHelp(p_dataElementList[i].children, p_requestPath, p_requestParams, p_helpParams);
            }
        }
    }

    function checkDataElementInParams(p_dataElement, p_requestPath, p_requestParams, p_helpParams, p_filtersThatCanBeParams) {
        for (var i = 0; i < p_requestParams.length; ++i) {
            if (p_requestParams[i].paramValue == undefined && p_dataElement.dataElement.typeDescriptor != undefined && p_dataElement.dataElement.typeDescriptor.typeName === p_helpParams[i].typeDescriptor.reference.typeName) {
                checkDataElementOnRequestPath(p_dataElement, p_requestPath, p_requestParams[i], p_filtersThatCanBeParams);
            }
        }
    }

    function checkDataElementOnRequestPath(p_dataElement, p_requestPath, p_param, p_filtersThatCanBeParams) {
        var request = v_fullRequest[p_requestPath[0]];
        if (request == undefined) {
            return;
        }
        if (checkDataCorrespondance(p_dataElement, request)) {
            p_param.paramValue = "%Parent0%";
        }
        for (var i = 1; i < p_requestPath.length; ++i) {
            if (request.getData)
                request = request.getData.children[p_requestPath[i]];
            else if (request.setData)
                request = request.setData.children[p_requestPath[i]];
            if (checkDataCorrespondance(p_dataElement, request)) {
                p_param.paramValue = "%Parent" + i +"%";
                return;
            }
        }
        if (p_filtersThatCanBeParams != undefined) {
            for (var i = 0; i < p_filtersThatCanBeParams.length; ++i) {
                request = p_filtersThatCanBeParams[i];
                if (request != undefined && checkDataCorrespondance(p_dataElement, request)) {
                    p_param.paramValue = "%FilterParent" + i +"%";
                    return;
                }
            }
        }
    }

    /**
        Check if actual request equals actual help dataelement, which is true if their name is equal and they have the same parameters.
    */
    function checkDataCorrespondance(p_dataElement, p_request) {
        var setOrGetData = getOrSetData(p_request);
        var ok = p_dataElement.dataElement.name === p_request[setOrGetData].element;
        if (p_dataElement.dataElement.parameters == undefined || p_dataElement.dataElement.parameters.length === 0) {
            return ok && (p_request[setOrGetData].params == undefined || p_request[setOrGetData].params.length === 0);
        }
        for (var i = 0; i < p_dataElement.dataElement.parameters.length && ok; ++i) {
            var helpParam = p_dataElement.dataElement.parameters[i];
            ok = ok && p_request[setOrGetData].params != undefined && p_request[setOrGetData].params[i] != undefined && helpParam.name === p_request[setOrGetData].params[i].paramName;
        }
        return ok;
    }

    ///////////////////// MOVING REQUEST IN THE TREE //////////////////////////////

    this.isValidToMoveRequest = function(p_fromPath, p_toPath) {
        var fromRequest = v_this.getRequestFromPath(p_fromPath);

        var fromParentPath = mcopy(p_fromPath);
        fromParentPath.pop();

        if (hasPrefix(p_toPath, fromParentPath)) {
            return true;
        } else if (hasPrefix(p_fromPath, p_toPath)) {
            var allowedParentsLessThan = p_toPath.length;
            var currentDepth = p_fromPath.length - 1;
            return checkAllowedParents(fromRequest, allowedParentsLessThan, currentDepth);
        } else {
            return false;
        }
    };

    function findMaxParent(str) {
        var pattern = new RegExp(PATTERN);
        var max = 0;
        var match = pattern.exec(str);
        if (match == undefined) {
            return undefined;
        }
        while (match != undefined) {
            if (match[1] > 0 && match[1] > max) {
                max = match[1];
            }
            match = pattern.exec(str);
        }
        return max;
    }

    function checkAllowedParents(request, allowedParentsLessThan, currentDepth) {
        var str = JSON.stringify(request);
        var maxparent = findMaxParent(str);
        if (maxparent != undefined && maxparent >= allowedParentsLessThan && maxparent < currentDepth) {
            return false;
        } else {
            return true
        }
    }

    function getOrSetData(request) {
        var setOrGetData = "getData";
        if (request && request.setData)
            setOrGetData = "setData";
        return setOrGetData;
    }
    this.moveRequest = function(p_fromPath, p_toPath, p_position) {
        var futureSiblingList;
        if (p_toPath.length == 0) {
            futureSiblingList = v_fullRequest;
        } else {
            var toParent = v_this.getRequestFromPath(p_toPath);
            toParent = toParent[getOrSetData(toParent)];
            if (toParent.children == undefined) {
                toParent.children = [];
            }
            futureSiblingList = toParent.children;
        }

        var request;
        var fromParentPath = mcopy(p_fromPath);
        var fromId = fromParentPath.pop();
        if (fromParentPath.length == 0) {
            request = v_fullRequest.splice(fromId, 1)[0];
        } else {
            var fromParent = v_this.getRequestFromPath(fromParentPath);
            fromParent = fromParent[getOrSetData(fromParent)];
            request = fromParent.children.splice(fromId, 1)[0];
            if (fromParent.children.length == 0 && fromParent.children != futureSiblingList) {
                fromParent.children = undefined;
            }
        }

        if (p_position > fromId && p_toPath.length === p_fromPath.length -1) {
            --p_position;
        }
        futureSiblingList.splice(p_position, 0, request);

        var fromDepth = p_fromPath.length - 1;
        var changeBy = p_toPath.length - (p_fromPath.length - 1);
        updateRequestParams(request, fromDepth, changeBy);
    };

    function incrementBy(str, fromDepth, amount, regex, suffix) {
        var pattern = new RegExp(regex);
        var match = pattern.exec(str);
        var radix = 10;
        var parentid = parseInt(match[1], radix);
        if (parentid >= fromDepth) {
            return "%Parent" + (parseInt(match[1], radix) + amount) + suffix + "%";
        } else {
            return str;
        }
    }

    function incrementParentBy(str, fromDepth, amount) {
        return incrementBy(str, fromDepth, amount, PATTERN, "");
    }

    function incrementParentIndexBy(str, fromDepth, amount) {
        return incrementBy(str, fromDepth, amount, PATTERN_IDX, "::idx");
    }

    function updateRequestParams(request, fromDepth, changeBy) {
        var setOrGetData = getOrSetData(request);
        var string = JSON.stringify(request[setOrGetData]);
        string = string.replace(new RegExp(PATTERN_IDX), function(match) {return incrementParentIndexBy(match, fromDepth, changeBy);});
        string = string.replace(new RegExp(PATTERN), function(match) {return incrementParentBy(match, fromDepth, changeBy);});
        request[setOrGetData] = JSON.parse(string);
    }
}
