package org.slc.sli.ingestion.transformation;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.slc.sli.ingestion.NeutralRecord;
import org.slc.sli.ingestion.dal.NeutralRecordMongoAccess;
import org.slc.sli.ingestion.validation.ErrorReport;

/**
 * Transformer for Assessment Entities
 *
 * @author ifaybyshev
 *
 */
public class AssessmentCombiner extends AbstractCombiner<NeutralRecordMongoAccess, String> {

    private static final Logger LOG = LoggerFactory.getLogger(AssessmentCombiner.class);

    private Map<String, HashMap<Object, NeutralRecord>> collections = new HashMap<String, HashMap<Object, NeutralRecord>>();

    private NeutralRecordMongoAccess neutralRecordMongoAccess;

    private String jobId;

    public AssessmentCombiner(NeutralRecordMongoAccess neutralRecordMongoAccess) {
        this.neutralRecordMongoAccess = neutralRecordMongoAccess;
    }

    @Override
    public void transform() {
        LOG.debug("Transforming data: Injecting schoolIds of all schools that teacher is a part of into teacher record");

        HashMap<Object, NeutralRecord> newCollection = new HashMap<Object, NeutralRecord>();
        String key;
        
        for (Map.Entry<Object, NeutralRecord> neutralRecordEntry : this.collections.get("teacher").entrySet()) {
            NeutralRecord neutralRecord = neutralRecordEntry.getValue();
            
            //get the key of parent
            Map<String, Object> attrs = neutralRecord.getAttributes();
            key = (String) attrs.get("body.staffUniqueStateId");
            
            //find children from database
            Map<String, String> paths = new HashMap<String, String>();
            paths.put("body.teacherId", key);
            
            Iterable<NeutralRecord> data = neutralRecordMongoAccess.getRecordRepository().findByPaths("teacherSchoolAssociation", paths);
            Iterator<NeutralRecord> iter = data.iterator();
            
            NeutralRecord tempNr;
            String schoolId;
            Map<String, Object> associationAttrs;
            Map<String, Object> schoolIds = new HashMap<String, Object>();
            
            while (iter.hasNext()) {
                tempNr = iter.next();
                associationAttrs = tempNr.getAttributes();
                schoolId = (String) associationAttrs.get("body.schoolId");
                
                schoolIds.put("schoolId", schoolId);
            }
            
            neutralRecord.setAttributes(schoolIds);
            newCollection.put(neutralRecord.getLocalId(), neutralRecord);
        }
        
        this.collections.put("modifiedTeacher", newCollection);
        
    }

    @Override
    public void loadData() {
        LOG.info("Loading data for transformation.");

        this.addCollection("teacher");
        this.addCollection("teacherSchoolAssociation");

        LOG.info("Teacher is loaded into local storage.  Total Count = " + this.collections.get("teacher").size());
        LOG.info("TeacherSchoolAssociation is loaded into local storage.  Total Count = " + this.collections.get("teacherSchoolAssociation").size());

    }

    @Override
    public String persist() {
        LOG.info("Persisting transformed data to storage.");

        for (Map.Entry<String, HashMap<Object, NeutralRecord>> collectionEntry : collections.entrySet()) {

            for (Map.Entry<Object, NeutralRecord> neutralRecordEntry : collectionEntry.getValue().entrySet()) {

                NeutralRecord neutralRecord = neutralRecordEntry.getValue();
                neutralRecord.setRecordType(neutralRecord.getRecordType() + "_transformed");

                neutralRecordMongoAccess.getRecordRepository().create(neutralRecord);
            }
        }

        return "OK";
    }

    /**
     * Stores all items in collection found in database to local storage (HashMap)
     *
     * @param collectionName
     */
    private void addCollection(String collectionName) {
        Iterable<NeutralRecord> data = neutralRecordMongoAccess.getRecordRepository().findAll(collectionName);
        Iterator<NeutralRecord> iter = data.iterator();

        HashMap<Object, NeutralRecord> collection = new HashMap<Object, NeutralRecord>();
        NeutralRecord tempNr;

        while (iter.hasNext()) {
            tempNr = iter.next();
            collection.put(tempNr.getLocalId(), tempNr);
        }

        this.collections.put(collectionName, collection);
    }

    /*
     * Transforms items inside staging database
     */
    @Override
    String doHandling(NeutralRecordMongoAccess item, ErrorReport errorReport) {
        LOG.info("Starting Transforming Assessments: Combining");

        String status = "FAIL";

        try {

            // Load data into local storage (memory)
            this.loadData();

            // perform transformations of the data in local storage
            this.transform();

            // persist transformed data to storage (i.e. db)
            status = this.persist();

        } catch (Exception e) {
            LOG.error("Exception", e);

            errorReport.fatal("Could not transform data.", AssessmentCombiner.class);
        }

        return status;
    }

    @Override
    public void setJobId(String id) {
        this.jobId = id;

    }

    public void setNeutralRecordMongoAccess(NeutralRecordMongoAccess neutralRecordMongoAccess) {
        this.neutralRecordMongoAccess = neutralRecordMongoAccess;
    }

}

@@ -1243,24 +1243,16 @@
 ng key;%0A
-        
 %0A       
@@ -1311,21 +1311,16 @@
 Entry : 
-this.
 collecti
@@ -1421,36 +1421,24 @@
 getValue();%0A
-            
 %0A           
@@ -1598,28 +1598,16 @@
 teId%22);%0A
-            
 %0A       
@@ -1758,28 +1758,16 @@
 , key);%0A
-            
 %0A       
@@ -1953,36 +1953,24 @@
 iterator();%0A
-            
 %0A           
@@ -2146,28 +2146,16 @@
 ect%3E();%0A
-            
 %0A       
@@ -2356,32 +2356,16 @@
 olId%22);%0A
-                
 %0A       
@@ -2424,28 +2424,16 @@
       %7D%0A
-            
 %0A       
@@ -2561,24 +2561,16 @@
       %7D%0A
-        
 %0A       
@@ -2562,37 +2562,32 @@
      %7D%0A%0A        
-this.
 collections.put(
@@ -2621,24 +2621,16 @@
 ction);%0A
-        
 %0A    %7D%0A%0A
@@ -2727,37 +2727,32 @@
 on.%22);%0A%0A        
-this.
 addCollection(%22t
@@ -2769,21 +2769,16 @@
         
-this.
 addColle
@@ -2880,37 +2880,32 @@
 tal Count = %22 + 
-this.
 collections.get(
@@ -3016,21 +3016,16 @@
 t = %22 + 
-this.
 collecti
@@ -4337,21 +4337,16 @@
         
-this.
 collecti
@@ -4726,21 +4726,16 @@
         
-this.
 loadData
@@ -4819,21 +4819,16 @@
         
-this.
 transfor
@@ -4915,21 +4915,16 @@
 tatus = 
-this.
 persist(

remove "this" verbosity