/*
 *  Copyright 2018 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * Singleton helper for formating stacktraces.
 * @private
 */
Ext.define('Ametys.plugins.coreui.system.devmode.StacktraceHelper', {
    singleton: true,
    
    /**
     * Unminify the stacktrace files and lines
     * @param {string} stacktrace The stacktrace
     * @param {Function} callback The callback that will receive the unminified stacktrace
     * @param {Object} opts Additional options for the server call
     */
    unminifyStacktrace: function(stacktrace, callback, opts)
    {
        opts = opts || {};
        var regex = /(?: at.+\(| at |@)([^) \n]+):([0-9]+):([0-9]+)/g;
        var stacktraceData = [];
        var match;
        while ((match = regex.exec(stacktrace)) !== null)
        {
            var filename = match[1].replace(window.location.protocol + '//' + window.location.host, "");
            var context = filename.indexOf(Ametys.CONTEXT_PATH) === 0 ? Ametys.CONTEXT_PATH : "";
            filename = filename.substr(context.length);

            stacktraceData.push({
                filename: filename,
                context: context,
                line: match[2],
                column: match[3]
            });
        }

        if (stacktraceData.length === 0)
        {
            callback(stacktrace);
            return;
        }

        Ametys.data.ServerComm.callMethod(Ext.applyIf(opts, {
            role: "org.ametys.plugins.core.ui.minimize.UnminimizeHelper",
            methodName: "unminifyStackTrace",
            parameters: [stacktraceData],
            callback: {
                handler: this._unminifyStacktraceCb,
                scope: this,
                arguments: {
                    stacktrace: stacktrace,
                    callback: callback
                },
                ignoreOnError: false
            }
        }));
    },

    /**
     * Callback receiving the server response with the callback data
     * @param {Object} response The server response
     * @param {Object} args The callback arguments
     * @private
     */
    _unminifyStacktraceCb: function(response, args)
    {
        if (response)
        {
            Ext.Array.forEach(response, function (data) {
                if (data.realFilename !== undefined)
                {
                    var oldStack = data.context + data.filename + ":" + data.line + ":" + data.column;
                    var realStack = data.realFilename + ":" + data.realLine + ":" + data.realColumn;
                    args.stacktrace = args.stacktrace.replace(oldStack, realStack);
                }
            });
        }

        args.callback(args.stacktrace);
    }
});