/**
 * Модуль, отвечающий за создание контекста безопасности (сессии).
 * 
 * Идентификатор сессии сохраняется в печеньках на клиенте.
 */
define([
    "dojo/_base/declare",
    "dojo/when",
    "implab/safe",
    "../Cookie",
    "../security/SecData",
    "../BaseResponse",
    "implab/log/trace!"
], function (declare, when, safe, Cookie, SecData, BaseResponse, trace) {
    let COOKIE_NAME = "ssid";
    
    return declare(null, {
        _request : null,
        _provider : null,
        _cookies : null,
        _sessionData: null,
        
        constructor : function(options) {
            safe.argumentNotNull(options, "options");
            safe.argumentNotNull(options.securityProvider, "options.securityProvider");
            safe.argumentNotNull(options.request, "options.request");
            
            this._request = options.request;
            this._provider = options.securityProvider;
            this._cookies = [];
        },
        
        /**
         * Вызывается из {SecurityHandler} по окончании обработки запроса.
         * 
         * @resp ответ сервера
         */
        completeRequest : function(resp) {
            trace.log("completeRequest");
            if (resp instanceof BaseResponse)
                this._cookies.forEach(function(cookie) {
                    resp.setCookie(cookie);
                });
            if (!safe.isNull(this._sessionData))
                return this._sessionData.save().then(function () {
                    return resp;
                });
            return resp;
        },
        
        handleError : function(err) {
            throw err;
        },
        
        initSession : function(userIdentity) {
            safe.argumentNotNull(userIdentity, "userIdentity");
            let me = this;
            
            return when(me._provider.getSessions().createSession(userIdentity, SecData.newSSID()), function(session) {
                if (!session) {
                    throw new Error("Can`t init session");
                }

                me._sessionData = session;
                trace.log("Created session {0} for user {1}", session.sessionId, userIdentity.getUser().login);
                me._cookies.push(new Cookie(COOKIE_NAME,session.sessionId));
                return session;
            });
        },
        
        /* aync */
        getSession : function() {
            let cookie;
            let me = this;
            try {
                cookie = this._request.cookie(COOKIE_NAME);
                
                if (!cookie)
                    return null;
                
                return when(me._provider.getSessions().getSession(cookie), function(session) {
                    me._sessionData = session;
                    return session;
                });
            } catch (e) {
                trace.log("getSession: {0}", e);
                return null;
            }
        }
    
    });
    
});