package org.slc.sli.ingestion.dal;

import java.util.Map;
import java.util.UUID;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;

import org.slc.sli.common.util.uuid.UUIDGeneratorStrategy;
import org.slc.sli.dal.encrypt.EntityEncryption;
import org.slc.sli.ingestion.NeutralRecord;

/**
 * Spring converter registered in the Mongo configuration to convert MongoEntity objects into
 * DBObjects.
 *
 */
public class NeutralRecordWriteConverter implements Converter<NeutralRecord, DBObject> {

    private EntityEncryption encryptor;

    @Autowired
    private UUIDGeneratorStrategy uuidGeneratorStrategy;

    public EntityEncryption getStagingEncryptor() {
        return encryptor;
    }

    public void setStagingEncryptor(EntityEncryption stagingEncryptor) {
        this.encryptor = stagingEncryptor;
    }

    @Override
    public DBObject convert(NeutralRecord neutralRecord) {

        Map<String, Object> body = neutralRecord.getAttributes();

        // Encrypt the neutral record for datastore persistence. TODO: Create a generic encryptor!
        Map<String, Object> encryptedBody = body;
        if (encryptor != null) {
            encryptedBody = encryptor.encrypt(neutralRecord.getRecordType(), neutralRecord.getAttributes());
        }

        UUID uid = null;
        if (neutralRecord.getRecordId() == null) {
            uid = uuidGeneratorStrategy.randomUUID();
            neutralRecord.setRecordId(uid.toString());
        } else {
            uid = UUID.fromString(neutralRecord.getRecordId());
        }

        BasicDBObject dbObj = new BasicDBObject();
        dbObj.put("type", neutralRecord.getRecordType());
        dbObj.put("_id", uid);
        dbObj.put("body", encryptedBody);
        dbObj.put("batchJobId", neutralRecord.getBatchJobId());
        dbObj.put("localId", neutralRecord.getLocalId());
        dbObj.put("localParentIds", neutralRecord.getLocalParentIds());
        dbObj.put("sourceFile", neutralRecord.getSourceFile());
        return dbObj;
    }
}

@@ -29,16 +29,68 @@
 n.dal;%0A%0A
+import java.util.LinkedList;%0Aimport java.util.List;%0A
 import j
@@ -191,16 +191,73 @@
 bject;%0A%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 import o
@@ -734,16 +734,115 @@
 ject%3E %7B%0A
+    private static final Logger LOG = LoggerFactory.getLogger(NeutralRecordWriteConverter.class);%0A%0A
 %0A    pri
@@ -1868,32 +1868,495 @@
 ());%0A        %7D%0A%0A
+        Map%3CString, Object%3E localParentIds = neutralRecord.getLocalParentIds();%0A        if (localParentIds != null) %7B%0A            // The old ingestion id resolver code used fields with %22.%22 in the name. This will cause the%0A            // mongo driver to throw an exception. If one of those fields exist in an entity being%0A            // saved to here, it is likely a legacy smooks config nobody bothered to update.%0A            cleanMap(localParentIds);%0A        %7D%0A%0A
         BasicDBO
@@ -2679,34 +2679,17 @@
 ntIds%22, 
-neutralRecord.getL
+l
 ocalPare
@@ -2693,18 +2693,16 @@
 arentIds
-()
 );%0A     
@@ -2787,11 +2787,942 @@
 j;%0A    %7D
+%0A%0A    @SuppressWarnings(%22unchecked%22)%0A    private static void cleanMap(Map%3CString, Object%3E map) %7B%0A        List%3CString%3E toRemove = new LinkedList%3CString%3E();%0A        for (String key : map.keySet()) %7B%0A            if (key.contains(%22.%22)) %7B%0A                toRemove.add(key);%0A                LOG.debug(%22Field being saved to mongo has a . in it.  Removing.  key: %7B%7D%22, key);%0A            %7D else %7B%0A                Object val = map.get(key);%0A                if (val instanceof Map) %7B%0A                    cleanMap((Map%3CString, Object%3E) val);%0A                %7D else if (val instanceof List) %7B%0A                    for (Object item : ((List%3CObject%3E) val)) %7B%0A                        if (item instanceof Map) %7B%0A                            cleanMap((Map%3CString, Object%3E) item);%0A                        %7D%0A                    %7D%0A                %7D%0A            %7D%0A        %7D%0A        for (String key : toRemove) %7B%0A            map.remove(key);%0A        %7D%0A    %7D
 %0A%7D%0A

fix issue caused by persisting localparentids.