package org.commcare.model.test;

import org.commcare.resources.model.Resource;
import org.commcare.resources.model.ResourceTable;
import org.commcare.suite.model.Profile;
import org.commcare.test.utils.PersistableSandbox;
import org.commcare.util.CommCareConfigEngine;
import org.commcare.xml.ProfileParser;
import org.javarosa.core.services.storage.util.DummyIndexedStorageUtility;
import org.javarosa.core.util.ArrayUtilities;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

/**
 * Regressions and unit tests for the profile model.
 * 
 * Covers functioning specific to the profile itself, not
 * to setup/usage of resource tables or other models.
 * 
 * @author ctsims
 */
public class ProfileTests {
    private PersistableSandbox mSandbox;
    private CommCareConfigEngine mAppPlatform;
    private ResourceTable mFreshResourceTable;
    
    @Before
    public void setUp() {
        mSandbox = new PersistableSandbox();
        mAppPlatform = new CommCareConfigEngine();
        mFreshResourceTable = ResourceTable.RetrieveTable(
                new DummyIndexedStorageUtility(ResourceTable.class));
    }
    
    @Test
    public void testProfileParse() {
        Profile p = getBasicProfile();
        assertEquals("Profile is not set to the correct version: (102)", p.getVersion(), 102);
    }
    
    @Test
    public void testProfileSerialization() {
        Profile p = getBasicProfile();
        byte[] serializedProfile = mSandbox.serialize(p);
        
        Profile deserialized = mSandbox.deserialize(serializedProfile, Profile.class);
        
        //Maybe this should just be p.equals(deserialized)? Kind of hard to say with deep
        //models of this type.
        compareProfiles(p, deserialized);
    }
    
    private void compareProfiles(Profile a, Profile b) {
        if(!ArrayUtilities.arraysEqual(a.getPropertySetters(), b.getPropertySetters())) {
            fail("Mismatch of property setters between profiles");
        }
        
        assertEquals("Mismatched auth references", a.getAuthReference(), b.getAuthReference());

        assertEquals("Mismatched profile versions", a.getVersion(), b.getVersion());
        
        //TOOD: compare root references and other mismatched fields
    }

    private Profile getBasicProfile() {
        try{
            String basicProfilePath = "basic_profile.ccpr";
            InputStream is = this.getClass().getClassLoader().getResourceAsStream("basic_profile.ccpr");
            if(is == null) {
                throw new RuntimeException("Test resource missing: " + basicProfilePath);
            }
            
            ProfileParser parser = new ProfileParser(is, mAppPlatform.getInstance(), mFreshResourceTable, "profile", 
                    Resource.RESOURCE_VERSION_UNKNOWN, false);
            
            return parser.parse();
        } catch(Exception e) {
            e.printStackTrace();
            throw PersistableSandbox.wrap("Error during profile test setup", e);
        }
    }
}

@@ -2788,16 +2788,16 @@
 .get
-Instance
+Platform
 (), 
@@ -2827,17 +2827,16 @@
 rofile%22,
- 
 %0A       

fix profile tests