/**
 * (c) by aheadware.com
 */

"use strict";

var app = app || {};
app.core = app.core || {};

/**
 */
app.core.Rpc = (function(){

    var endpoint = null;

    var fnSendRpc, fnProcessError;

    fnProcessError = function( errorMsg, code )
    {
        let msg = '';

        switch( code )
        {
            case 401:
                app.core.View.alert( _lc( 'NOT_LOGGED_IN' ), function()
                {
                    var redirectUrl = '?redirect=' + app.util.Helper.trim( app.core.Controller.getCurrentRoute(), '#' );
                    app.core.Controller.redirect( '#/auth/logout' + redirectUrl );
                });
            break;

            case 404:
                msg = 'Resource not found.';
                app.core.View.toastError( msg );
                app.gui.PageLoader.hide();
            break;

            // Outdated version
            case 899:
                app.core.View.alert( _lc( 'SYNC_VERSION_WITH_SERVER' ), function()
                {
                    app.core.Controller.reload( true );
                });
            break;

            case 500:
            default:
                msg = 'General server error.';
                app.core.View.toastError( msg );
                app.gui.PageLoader.hide();

        }
    };

    fnSendRpc = function( controller, action, params, onSuccess, onError )
    {
        var onSuccess = onSuccess || null,
            xhr = new XMLHttpRequest(),
            request = {
                auth : {
                    version : app.core.App.getConfig( 'version' ),
                    sessionToken : app.core.Session.getToken()
                },
                c : controller,
                a: action,
                params : params || null
            };

        xhr.onload = function()
        {
            var response = xhr.responseText,
                responseCode = 500;

            if ( response )
            {
                try
                {
                    // RpcResponse should have a structure of this
                    // { code: {int}, data : {*} }
                    response = JSON.parse( response );

                    if ( !response.hasOwnProperty( 'code' ) || !response.hasOwnProperty( 'data' ) )
                    {
                        fnProcessError( "Invalid response.", 500 );
                    }
                    else
                    {
                        responseCode = +response.code;
                    }
                }
                catch( err )
                {
                    response = null;
                    responseCode = 500;
                }
            }
            if ( 4 === xhr.readyState && 200 === responseCode )
            {
                if ( 200 == responseCode )
                {
                    onSuccess && onSuccess( response.data );
                }
                else
                {
                    if ( onError && "function" === typeof onError )
                    {
                        onError && onError( response.data, responseCode );
                    }
                    else
                    {
                        fnProcessError( response.data, responseCode);
                    }
                }
            }
            else
            {
                if ( onError && "function" === typeof onError )
                {
                    onError && onError( "XHR error", responseCode );
                }
                else
                {
                    fnProcessError( "XHR error", responseCode );
                }
            }
        };

        xhr.onerror = function()
        {
            if ( onError && "function" === typeof onError )
            {
                onError && onError( "XHR error", 500 );
            }
            else
            {
                fnProcessError( "XHR error", 500 );
            }

        };

        xhr.onabort = function()
        {
            if ( onError && "function" === typeof onError )
            {
                onError && onError( "XHR abort", 500 );
            }
            else
            {
                fnProcessError( "XHR error", xhr.status);
            }
        };

        xhr.open( "POST", endpoint );
        xhr.setRequestHeader( "Content-Type", "application/json" );
        xhr.send( JSON.stringify( request ) );

        return xhr;
    };

    return {
        call : function( controller, action, params, onSuccess, onError )
        {
            return fnSendRpc(
                controller,
                action,
                params || null,
                onSuccess || null,
                onError || null
            );
        }
        ,
        init : function( endpointUrl )
        {
            endpoint = endpointUrl;
        }
    };

})();