// 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 GuiEditor_SanityChecker_ViewModel(p_model, p_parent) {
    "use strict";

    var v_model = p_model;
    var v_fileHandler = v_model.getFileHandler();
    var v_parent = p_parent;

    var v_help;
    var v_request;
    var v_cache;
    var v_ajv_validator;

    var v_this = this;

    ///////////////////// GENERAL VIEWMODEL FUNCTIONS /////////////////////

    this.init = function(p_callback) {
        v_cache = {};

        v_ajv_validator = new Ajv({schemaId: 'id'});
        v_ajv_validator.addFormat('checkbox', function (value) {return true;});
        v_ajv_validator.addFormat('tabs', function (value) {return true;});
        v_ajv_validator.addFormat('table', function (value) {return true;});
        var metasch = v_model.getMetaSchema();
        v_ajv_validator.addMetaSchema(metasch);

        function jsImported(ok, data) {
            if (!ok) {
                alert("Some javascript files could not be imported\n" + JSON.stringify(data, null, 4));
            }
            p_callback(true);
        }

        new MultipleDirectoryListTask([
                v_model.getAppConfig().lastEditedApp + "/ViewModels",
                "WebApplications/CustomizableApp/ViewModels",
                v_model.getAppConfig().lastEditedApp + "/Views",
                "WebApplications/CustomizableApp/Views"
            ], v_fileHandler).taskOperation(function(ok, resources) {
            new JsImportTaskList(resources.jsfiles, v_fileHandler, jsImported).taskOperation();
        });
    };

    this.setHelp = function(p_help) {
        v_help = p_help;
    };

    this.setSetup = function(p_setup) {
        v_request = p_setup.request.getData();
    };

    this.addFile = function(fileName) {
        v_fileHandler.importJsFile(fileName, function(ok, msg) {
            if (!ok) {
                alert("Javascript file invalid, import failed: " + fileName + "\n" + msg);
            }
        });
    };

    ///////////////////// INTERFACE FOR VALIDATION AND GETTING HELP /////////////////////

    this.isValidView = function(view, connectedViewmodels) {
        var viewClass = view.getClass();
        if (window[viewClass] != undefined) {
            // check expected interfaces
            if (window[viewClass].expectsInterface != undefined) {
                var expectedInterfaces = window[viewClass].expectsInterface();
                for (var i = 0; i < connectedViewmodels.length; ++i) {
                    var viewmodelClass = connectedViewmodels[i].getClass();
                    if (window[viewmodelClass] != undefined && window[viewmodelClass].providesInterface != undefined) {
                        var providedInterface = window[viewmodelClass].providesInterface();
                        var useful = false;
                        for (var j = 0; j < expectedInterfaces.length; ++j) {
                            var listToSearch = findMandatoryOrOptional(expectedInterfaces[j]);;
                            if (listToSearch != undefined && isSubsetOf(listToSearch, providedInterface)) {
                                expectedInterfaces[j].fulfilled = true;
                                useful = true;
                            }
                        }
                        if (!useful) {
                            return "connected viewmodel " + i + " of class " + viewmodelClass + " does not provide an expected interface";
                        }
                    }
                }

                for (var i = 0; i < expectedInterfaces.length; ++i) {
                    if (!expectedInterfaces[i].fulfilled && expectedInterfaces[i].mandatory != undefined) {
                        return "an interface is not fulfilled: " + expectedInterfaces[i].mandatory;
                    }
                }
            }

            // chack if custom data is valid
            if (window[viewClass].getCustomDataSchema != undefined && !oldff) {
                var isValid = v_ajv_validator.validate(window[viewClass].getCustomDataSchema(), view.getCustomData());
                if (!isValid) {
                    return "custom data does not match the schema";
                }
            }
        }

        return "";
    };

    this.isValidViewmodel = function(viewmodel) {
        var viewmodelClass = viewmodel.getClass();
        if (window[viewmodelClass] != undefined) {
            // chack if custom data is valid
            if (window[viewmodelClass].getCustomDataSchema != undefined && !oldff) {
                var isValid = v_ajv_validator.validate(window[viewmodelClass].getCustomDataSchema(), viewmodel.getCustomData());
                if (!isValid) {
                    return "custom data does not match the schema";
                }
            }
            // check request connections
            if (window[viewmodelClass].expectsConnection != undefined) {
                var expectedConnections = window[viewmodelClass].expectsConnection();
                var dataConnections = viewmodel.getDataConnections();
                var selectionConnections = viewmodel.getSelectionConnections();
                var connectionsOk = checkRequestToViewmodelConnections(dataConnections, selectionConnections, expectedConnections);
                if (connectionsOk != "") {
                    return connectionsOk;
                }
            }
        }

        return "";
    };

    this.getHelp = function(className) {
        if (window[className] != undefined && window[className].getHelp != undefined) {
            return window[className].getHelp();
        } else {
            return "No help available for " + className;
        }
    };

    this.getCustomDataSchema = function(className) {
        if (window[className] != undefined && window[className].getCustomDataSchema != undefined) {
            return window[className].getCustomDataSchema();
        } else {
            return undefined;
        }
    };

    ///////////////////// PRIVATE FUNCTIONS /////////////////////

    function isSubsetOf(subset, set) {
        var found = true;
        for (var j = 0; j < subset.length && found; ++j) {
            found = set.indexOf(subset[j]) != -1;
        }
        return found;
    }

    function findMandatoryOrOptional(expectedInterfaces) {
        if (expectedInterfaces.mandatory != undefined) {
            return expectedInterfaces.mandatory;
        } else if (expectedInterfaces.optional != undefined) {
            return expectedInterfaces.optional;
        } else {
            return undefined;
        }
    }

    function checkRequestToViewmodelConnections(dataConnections, selectionConnections, expectedConnections) {
        var expectedDataConnections = expectedConnections.dataConnections;
        if (expectedDataConnections != undefined) {
            if (expectedDataConnections.length == 0 && dataConnections.length > 0) {
                return "no data connections expected";
            }

            for (var i = 0; i < dataConnections.length; ++i) {

                var expectedConnectionIndex = Math.min(i, expectedDataConnections.length - 1);
                var expectedConnection = expectedDataConnections[expectedConnectionIndex];
                if (i >= expectedDataConnections.length && expectedConnectionIndex == expectedDataConnections.length - 1 && expectedConnection.multiple !== true) {
                    return "more data connections detected than expected";
                }

                var result = checkRequestToViewmodelConnection(dataConnections, selectionConnections, expectedConnection, dataConnections, i, "data connection");
                if (result != "") {
                    return result;
                }
            }

            if (expectedDataConnections[dataConnections.length] != undefined && (expectedDataConnections[dataConnections.length].optional == undefined || expectedDataConnections[dataConnections.length].optional == false)) {
                return "missing non optional data connection";
            }
        }

        var expectedSelectionConnections = expectedConnections.selectionConnections;
        if (expectedSelectionConnections != undefined) {
            if (expectedSelectionConnections.length == 0 && selectionConnections.length > 0) {
                return "no selection connections expected";
            }

            for (var i = 0; i < selectionConnections.length; ++i) {

                var expectedConnectionIndex = Math.min(i, expectedSelectionConnections.length - 1);
                var expectedConnection = expectedSelectionConnections[expectedConnectionIndex];
                if (i >= expectedDataConnections.length && expectedConnectionIndex == expectedSelectionConnections.length - 1 && expectedConnection.multiple !== true) {
                    return "more selection connections detected than expected";
                }

                var result = checkRequestToViewmodelConnection(dataConnections, selectionConnections, expectedConnection, selectionConnections, i, "selection connection");
                if (result != "") {
                    return result;
                }

                if (expectedSelectionConnections[selectionConnections.length] != undefined && (expectedSelectionConnections[selectionConnections.length].optional == undefined || expectedSelectionConnections[selectionConnections.length].optional == false)) {
                    return "missing non optional selection connection";
                }
            }
        }

        return "";
    }

    function checkRequestToViewmodelConnection(dataConnections, selectionConnections, expectedConnection, connections, indexOfConnection, connectionType) {
        if (expectedConnection.childOfDataConnection != undefined) {
            if (dataConnections[expectedConnection.childOfDataConnection] == undefined || !hasPrefix(connections[indexOfConnection], dataConnections[expectedConnection.childOfDataConnection])) {
                return connectionType + " " + indexOfConnection + " is not a child of data connection " + expectedConnection.childOfDataConnection;
            }
        }

        var request = getRequestFromPath(connections[indexOfConnection]);

        if (expectedConnection.element != undefined && expectedConnection.element != request.getData.element) {
            return "wrong element found for " + connectionType + " " + indexOfConnection + ", expected " + expectedConnection.element;
        }
        if (expectedConnection.source != undefined && expectedConnection.source != request.getData.source) {
            return "wrong source found for " + connectionType + " " + indexOfConnection + ", expected " + expectedConnection.source;
        }
        if (expectedConnection.filter == true && request.getData.filter == undefined) {
            return "expected a filter for " + connectionType + " " + indexOfConnection;
        }

        if (expectedConnection.valueType != undefined) {
            var helpDataElement = getHelpFromRequest(request).dataElement;
            if (helpDataElement != undefined && expectedConnection.valueType.indexOf(helpDataElement.valueType) == -1) {
                return "wrong value type for " + connectionType + " " + indexOfConnection + ", expected " + expectedConnection.valueType;
            }
        }

        if (
            expectedConnection.dataElementOfDataConnection != undefined && (
                dataConnections[expectedConnection.dataElementOfDataConnection] == undefined ||
                getHelpFromRequest(request).index != getHelpFromRequest(getRequestFromPath(dataConnections[expectedConnection.dataElementOfDataConnection])).index
            )
        ) {
            return connectionType + " " + indexOfConnection + " is not the same element as data connection " + expectedConnection.dataElementOfDataConnection;
        }

        return "";

    }

    function getRequestFromPath(p_path) {
        var request = v_request[p_path[0]];
        for (var i = 1; i < p_path.length; ++i) {
            request = request.getData.children[p_path[i]];
        }
        return request;
    }

    function hasPrefix(path, prefix) {
        for (var i = 0; i < prefix.length; ++i) {
            if (path[i] == undefined || path[i] != prefix[i]) {
                return false;
            }
        }
        return true;
    }

    function getHelpFromRequest(request) {
        var requestHash = getRequestHash(request);
        if (v_cache[requestHash] != undefined) {
            return v_cache[requestHash];
        }

        var result;
        var bestIndex;
        var bestScore = 0;
        var source = request.getData.source;
        if (v_help)
            for (var i = 0; i < v_help.sources.length; ++i) {
                if (v_help.sources[i].source == source) {
                    for (var j = 0; j < v_help.sources[i].dataElements.length; ++j) {
                        var score = isCorrectElementForRequest(v_help.sources[i].dataElements[j].dataElement, request);
                        if (score > bestScore) {
                            result = {
                                "index": j,
                                "dataElement": v_help.sources[i].dataElements[j].dataElement
                            };
                            bestScore = score;
                        }
                    }
                }
            }

        if (bestScore == 0) {
            result = {
                "index": -1
            }
        }

        v_cache[requestHash] = result;
        return result;
    }

    function isCorrectElementForRequest(dataElement, request) {
        if (dataElement.name != request.getData.element) {
            return 0;
        }

        var score = 1;
        var params = getParamTypes(request);
        if (dataElement.parameters != undefined) {
            for (var i = 0; i < dataElement.parameters.length; ++i) {
                if (dataElement.parameters[i].typeDescriptor != undefined && dataElement.parameters[i].typeDescriptor.reference != undefined && dataElement.parameters[i].typeDescriptor.reference.typeName != undefined) {
                    if (params.indexOf(dataElement.parameters[i].typeDescriptor.reference.typeName) != -1) {
                        ++score;
                    }
                }
            }
        }

        return score;
    }

    function getRequestHash(request) {
        var hash = request.getData.source + "." + request.getData.element;
        var params = getParamTypes(request);
        for (var i = 0; i < params.length; ++i) {
            hash += "." + params[i];
        }

        return hash;
    }

    function getParamTypes(request) {
        var params = [];
        if (request.getData.params != undefined) {
            for (var i = 0; i < request.getData.params.length; ++i) {
                params.push(request.getData.params[i].paramName);
            }
        }
        params.sort();
        return params;
    }
}
//# sourceURL=GuiEditor\ViewModels\ViewModel_SanityChecker.js