// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

/**
 * Override the Shopware class loader, i.e. Ext.Loader, to filter out any modules that are known dependencies of other
 * modules of the same namespace. These dependencies MUST NOT be loaded via Shopware's class loader. Instead the loading
 * of the dependent app should be delayed until the code of its dependencies is loaded, that is defined. Therefore we
 * save the loading callback of those dependent modules in the viisonDependencies list and trigger it once the code of
 * the dependency is loaded.
 *
 * See ../base.js for further info on how we collect those dependencies as well as completing the delayed loading.
 */
(function () {
    Ext.Loader.viisonDependencies = {};

    // Override Shopware's class loader to prevent knwon dependencies from being loaded
    var originalLoaderRequire = Ext.Loader.require;
    Ext.Loader.require = function (moduleNames, fn, scope) {
        // Filter out any module names that are known dependencies
        var normalizedModuleNames = (Ext.isString(moduleNames)) ? [moduleNames] : moduleNames;
        var foundViisonDependencies = false;
        var filteredModuleNames = [];
        Ext.Array.forEach(normalizedModuleNames, function (expression) {
            if (Ext.isArray(this.viisonDependencies[expression]) && !Ext.ClassManager.isCreated(expression)) {
                // Module is a known dependency, hence add the loading callback to the queue
                foundViisonDependencies = true;
                this.viisonDependencies[expression].push({
                    fn: fn,
                    scope: scope,
                });
            } else {
                // No known dependency, hence keep the module name for the original loader
                filteredModuleNames.push(expression);
            }
        }, this);

        // Only skip the original loader, if we found dependencies and as a result the filtered list is empty,
        // because otherwise no classes would be loaded
        if (foundViisonDependencies && filteredModuleNames.length === 0) {
            return this;
        }

        // Pass the filtered module names to the original loader
        var modifiedArguments = arguments;
        modifiedArguments[0] = filteredModuleNames;

        return originalLoaderRequire.apply(Ext.Loader, modifiedArguments);
    };
}());
