package org.orienteer.core.module;

import com.google.inject.Singleton;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.metadata.security.OUser;
import com.orientechnologies.orient.core.query.OQuery;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
import org.apache.wicket.ISessionListener;
import org.apache.wicket.Session;
import org.orienteer.core.OrienteerWebApplication;
import org.orienteer.core.util.OSchemaHelper;
import ru.ydn.wicket.wicketorientdb.utils.DBClosure;

/**
 * @author Kirill Mukhov
 */
@Singleton
public class UserOnlineModule extends AbstractOrienteerModule {

    public static final String NAME = "user-online";
    public static final String OCLASS_USER = "OUser";

    public static final String ONLINE_FIELD = "online";
    public static final String LAST_SESSION_FIELD = "lastSessionId";

    public UserOnlineModule() {
        super(NAME, 1);
    }

    @Override
    public ODocument onInstall(OrienteerWebApplication app, ODatabaseDocument db) {
        super.onInstall(app, db);
        OSchemaHelper helper = OSchemaHelper.bind(db);

        helper.oClass(OCLASS_USER)
                .oProperty(ONLINE_FIELD, OType.BOOLEAN)
                .oProperty(LAST_SESSION_FIELD, OType.STRING)
                .switchDisplayable(true, ONLINE_FIELD, LAST_SESSION_FIELD);

        return null;
    }

    @Override
    public void onInitialize(OrienteerWebApplication app, ODatabaseDocument db) {
        super.onInitialize(app, db);
        app.getSessionListeners().add(new ISessionListener() {
            @Override
            public void onCreated(Session session) { }

            @Override
            public void onUnbound(final String sessionId) {
                new DBClosure<Void>() {
                    @Override
                    protected Void execute(ODatabaseDocument db) {
                        db.command(new OSQLSynchQuery<Void>("UPDATE " + OCLASS_USER + " set " +
                                ONLINE_FIELD + "=false where " + LAST_SESSION_FIELD + "=\""+sessionId + "\""));
                        return null;
                    }
                }.execute();
            }
        });
    }

    public ODocument updateOnlineUser(OUser user, final boolean online) {
        final ODocument document = user.getDocument();
        return new DBClosure<ODocument>() {
            @Override
            protected ODocument execute(ODatabaseDocument oDatabaseDocument) {
                document.field(ONLINE_FIELD, online);
                document.save();
                return document;
            }
        }.execute();
    }

    public void updateSessionUser(OUser user, final String sessionId) {
    	if(user!=null) { 
	        final ODocument document = user.getDocument();
	        new DBClosure<ODocument>() {
	            @Override
	            protected ODocument execute(ODatabaseDocument oDatabaseDocument) {
	                document.field(LAST_SESSION_FIELD, sessionId);
	                document.save();
	                return document;
	            }
	        }.execute();
    	}
    }
}

@@ -378,32 +378,90 @@
 impl.ODocument;%0A
+import com.orientechnologies.orient.core.sql.OCommandSQL;%0A
 import com.orien
@@ -681,24 +681,82 @@
 hemaHelper;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A
 import ru.yd
@@ -808,29 +808,57 @@
 %0A * 
-@author Kirill Mukhov
+Module to support user's online/offline lifecycle
 %0A */
@@ -2213,27 +2213,18 @@
 ew O
-SQLSynchQuery%3CVoid%3E
+CommandSQL
 (%22UP
@@ -2348,12 +2348,22 @@
 + %22=
-%5C%22%22+
+ ?%22)).execute(
 sess
@@ -2371,16 +2371,8 @@
 onId
- + %22%5C%22%22)
 );%0A 
@@ -2525,24 +2525,30 @@
 eOnlineUser(
+final 
 OUser user, 
@@ -2575,63 +2575,8 @@
 ) %7B%0A
-        final ODocument document = user.getDocument();%0A
     
@@ -2712,24 +2712,93 @@
 Document) %7B%0A
+            %09final ODocument document = user.reload().getDocument();%0A
             
@@ -2981,16 +2981,22 @@
 ionUser(
+final 
 OUser us
@@ -3052,64 +3052,8 @@
  %7B %0A
-%09        final ODocument document = user.getDocument();%0A
 %09   
@@ -3185,24 +3185,94 @@
 Document) %7B%0A
+%09            %09final ODocument document = user.reload().getDocument();%0A
 %09           

Fix issues with user online module: fix #326