package org.commcare.core.process;

import org.commcare.core.interfaces.UserDataInterface;
import org.commcare.cases.instance.CaseInstanceTreeElement;
import org.commcare.cases.ledger.instance.LedgerInstanceTreeElement;
import org.commcare.core.sandbox.SandboxUtils;
import org.commcare.suite.model.User;
import org.commcare.util.CommCarePlatform;
import org.commcare.util.CommCareSession;
import org.javarosa.core.model.instance.AbstractTreeElement;
import org.javarosa.core.model.instance.ExternalDataInstance;
import org.javarosa.core.model.instance.FormInstance;
import org.javarosa.core.model.instance.InstanceInitializationFactory;
import org.javarosa.core.model.instance.TreeElement;

/**
 *  Initializes a CommCare DataInstance against a UserDataInterface and (sometimes) optional
 *  CommCareSession/Platform
 *
 * @author ctsims
 * @author wspride
 */
public class CommCareInstanceInitializer extends InstanceInitializationFactory {

    protected final CommCareSession session;
    protected CaseInstanceTreeElement casebase;
    protected LedgerInstanceTreeElement stockbase;
    protected final UserDataInterface mSandbox;
    protected final CommCarePlatform mPlatform;


    public CommCareInstanceInitializer(UserDataInterface sandbox) {
        this(null, sandbox, null);
    }

    public CommCareInstanceInitializer(UserDataInterface sandbox, CommCarePlatform platform) {
        this(null, sandbox, platform);
    }

    public CommCareInstanceInitializer(UserDataInterface sandbox, CommCareSession session) {
        this(session, sandbox, null);
    }

    public CommCareInstanceInitializer(CommCareSession session, UserDataInterface sandbox, CommCarePlatform platform) {
        this.session = session;
        this.mSandbox = sandbox;
        this.mPlatform = platform;
    }

    public AbstractTreeElement generateRoot(ExternalDataInstance instance) {
        String ref = instance.getReference();
        if (ref.contains(LedgerInstanceTreeElement.MODEL_NAME)) {
            if (stockbase == null) {
                stockbase = new LedgerInstanceTreeElement(instance.getBase(), mSandbox.getLedgerStorage());
            } else {
                //re-use the existing model if it exists.
                stockbase.rebase(instance.getBase());
            }
            return stockbase;
        } else if (ref.contains(CaseInstanceTreeElement.MODEL_NAME)) {
            if (casebase == null) {
                casebase = new CaseInstanceTreeElement(instance.getBase(), mSandbox.getCaseStorage(), false);
            } else {
                //re-use the existing model if it exists.
                casebase.rebase(instance.getBase());
            }
            return casebase;
        } else if (instance.getReference().contains("fixture")) {
            //TODO: This is all just copied from J2ME code. that's pretty silly. unify that.
            String userId = "";
            User u = mSandbox.getLoggedInUser();

            if (u != null) {
                userId = u.getUniqueId();
            }

            String refId = ref.substring(ref.lastIndexOf('/') + 1, ref.length());
            try {
                FormInstance fixture = SandboxUtils.loadFixture(mSandbox, refId, userId);

                if (fixture == null) {
                    throw new RuntimeException("Could not find an appropriate fixture for src: " + ref);
                }

                TreeElement root = fixture.getRoot();
                root.setParent(instance.getBase());
                return root;

            } catch (IllegalStateException ise) {
                throw new RuntimeException("Could not load fixture for src: " + ref);
            }
        }
        if (instance.getReference().contains("session")) {
            if(this.mPlatform == null) {
                throw new RuntimeException("Cannot generate session instance with undeclared platform!");
            }
            User u = mSandbox.getLoggedInUser();
            TreeElement root = session.getSessionInstance(getDeviceId(), getVersionString(), u.getUsername(), u.getUniqueId(), u.getProperties()).getRoot();
            root.setParent(instance.getBase());
            return root;
        }
        return null;
    }

    protected String getDeviceId(){
        return "----";
    }

    protected String getVersionString(){
        return "CommCare CLI: " + mPlatform.getMajorVersion() + "." + mPlatform.getMinorVersion();
    }
}

@@ -1934,24 +1934,23 @@
 if (ref.
-contains
+indexOf
 (LedgerI
@@ -1971,32 +1971,38 @@
 ment.MODEL_NAME)
+ != -1
 ) %7B%0A            
@@ -2334,24 +2334,23 @@
 if (ref.
-contains
+indexOf
 (CaseIns
@@ -2377,16 +2377,22 @@
 EL_NAME)
+ != -1
 ) %7B%0A    
@@ -2751,24 +2751,23 @@
 rence().
-contains
+indexOf
 (%22fixtur
@@ -2769,16 +2769,22 @@
 ixture%22)
+ != -1
 ) %7B%0A    
@@ -3730,16 +3730,15 @@
 e().
-contains
+indexOf
 (%22se
@@ -3744,16 +3744,22 @@
 ession%22)
+ != -1
 ) %7B%0A    

move packages