package org.commcare.session;

import org.commcare.suite.model.StackFrameStep;
import org.javarosa.core.model.data.UncastData;
import org.javarosa.core.model.instance.FormInstance;
import org.javarosa.core.model.instance.TreeElement;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

public class SessionInstanceBuilder {
    public static FormInstance getSessionInstance(SessionFrame frame, String deviceId,
                                                  String appversion, String username,
                                                  String userId,
                                                  Hashtable<String, String> userFields) {
        TreeElement sessionRoot = new TreeElement("session", 0);
        TreeElement sessionData = new TreeElement("data", 0);

        sessionRoot.addChild(sessionData);

        for (StackFrameStep step : frame.getSteps()) {
            if (SessionFrame.STATE_DATUM_VAL.equals(step.getType())) {
                Vector<TreeElement> matchingElements =
                        sessionData.getChildrenWithName(step.getId());

                if (matchingElements.size() > 0) {
                    matchingElements.elementAt(0).setValue(new UncastData(step.getValue()));
                } else {
                    TreeElement datum = new TreeElement(step.getId());
                    datum.setValue(new UncastData(step.getValue()));
                    sessionData.addChild(datum);
                }
            }
        }

        TreeElement sessionMeta = new TreeElement("context", 0);

        addData(sessionMeta, "deviceid", deviceId);
        addData(sessionMeta, "appversion", appversion);
        addData(sessionMeta, "username", username);
        addData(sessionMeta, "userid", userId);

        sessionRoot.addChild(sessionMeta);

        TreeElement user = new TreeElement("user", 0);
        TreeElement userData = new TreeElement("data", 0);
        user.addChild(userData);
        for (Enumeration en = userFields.keys(); en.hasMoreElements(); ) {
            String key = (String) en.nextElement();
            addData(userData, key, userFields.get(key));
        }

        sessionRoot.addChild(user);

        return new FormInstance(sessionRoot, "session");
    }

    private static void addData(TreeElement root, String name, String data) {
        TreeElement datum = new TreeElement(name);
        datum.setValue(new UncastData(data));
        root.addChild(datum);
    }
}

@@ -738,24 +738,336 @@
 ession%22, 0);
+%0A%0A        addDatums(sessionRoot, frame);%0A        addMetadata(sessionRoot, deviceId, appversion, username, userId);%0A        addUserProperties(sessionRoot, userFields);%0A%0A        return new FormInstance(sessionRoot, %22session%22);%0A    %7D%0A%0A    private static void addDatums(TreeElement sessionRoot, SessionFrame frame) %7B
 %0A        Tre
@@ -1157,25 +1157,24 @@
 ssionData);%0A
-%0A
         for 
@@ -1806,32 +1806,241 @@
     %7D%0A        %7D%0A
+    %7D%0A%0A    private static void addMetadata(TreeElement sessionRoot, String deviceId,%0A                                    String appversion, String username,%0A                                    String userId) %7B
 %0A        TreeEle
@@ -2342,16 +2342,171 @@
 nMeta);%0A
+    %7D%0A%0A    private static void addUserProperties(TreeElement sessionRoot,%0A                                          Hashtable%3CString, String%3E userFields) %7B
 %0A       
@@ -2753,17 +2753,16 @@
 (String)
- 
 en.nextE
@@ -2880,65 +2880,8 @@
 );%0A%0A
-        return new FormInstance(sessionRoot, %22session%22);%0A
     
@@ -3094,10 +3094,11 @@
 ;%0A    %7D%0A
+%0A
 %7D%0A

Refactor session instance building