package org.slc.sli.ingestion.smooks;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.milyn.Smooks;
import org.milyn.delivery.Visitor;
import org.xml.sax.SAXException;

import org.slc.sli.ingestion.FileType;
import org.slc.sli.ingestion.NeutralRecord;
import org.slc.sli.ingestion.NeutralRecordFileWriter;
import org.slc.sli.ingestion.ResourceWriter;
import org.slc.sli.ingestion.dal.NeutralRecordMongoAccess;
import org.slc.sli.ingestion.landingzone.IngestionFileEntry;
import org.slc.sli.ingestion.validation.ErrorReport;

/**
 * Factory class for Smooks
 *
 * @author dduran
 *
 */
public class SliSmooksFactory {

    private Map<FileType, SliSmooksConfig> sliSmooksConfigMap;
    private String beanId;
    private NeutralRecordMongoAccess nrMongoStagingWriter;
    private Map<String, Smooks> mapSmooks = new HashMap<String, Smooks>();

    public Smooks createInstance(IngestionFileEntry ingestionFileEntry, NeutralRecordFileWriter fileWriter,
            ErrorReport errorReport) throws IOException, SAXException {

        FileType fileType = ingestionFileEntry.getFileType();
        SliSmooksConfig sliSmooksConfig = sliSmooksConfigMap.get(fileType);
        if (sliSmooksConfig != null) {

            return createSmooksFromConfig(sliSmooksConfig, fileWriter, errorReport, ingestionFileEntry.getBatchJobId(),
                    ingestionFileEntry);

        } else {
            errorReport.fatal("File type not supported : " + fileType, SliSmooksFactory.class);
            throw new IllegalArgumentException("File type not supported : " + fileType);
        }
    }

    private Smooks createSmooksFromConfig(SliSmooksConfig sliSmooksConfig, NeutralRecordFileWriter fileWriter,
            ErrorReport errorReport, String batchJobId, IngestionFileEntry fe) throws IOException, SAXException {

        Smooks smooks = fetchSmooks(sliSmooksConfig);

        // based on target selectors for this file type, add visitors
        List<String> targetSelectorList = sliSmooksConfig.getTargetSelectors();
        if (targetSelectorList != null) {

            // just one visitor instance that can be added with multiple target selectors
            Visitor smooksEdFiVisitor = SmooksEdFiVisitor.createInstance(beanId, batchJobId, fileWriter, errorReport,
                    fe);

            nrMongoStagingWriter.registerBatchId(batchJobId);
            nrMongoStagingWriter.ensureIndex();

            ((SmooksEdFiVisitor) smooksEdFiVisitor).setNrMongoStagingWriter(nrMongoStagingWriter);
            for (String targetSelector : targetSelectorList) {
                smooks.addVisitor(smooksEdFiVisitor, targetSelector);
            }
        }
        return smooks;
    }

    /**
     * Returns a Smooks object for the given config, either from cache or by constructing a new
     * instance. Constructing smooks objects are slow, hence our use of a cache.
     *
     * @param sliSmooksConfig
     * @return
     * @throws IOException
     * @throws SAXException
     */
    private Smooks fetchSmooks(SliSmooksConfig sliSmooksConfig) throws IOException, SAXException {

        String configName = sliSmooksConfig.getConfigFileName();
        Smooks inCache = mapSmooks.get(configName);
        if (inCache == null) {
            Smooks smooks = new Smooks(configName);
            mapSmooks.put(configName, smooks);
            return smooks;
        } else {
            return inCache;
        }
    }

    public void setSliSmooksConfigMap(Map<FileType, SliSmooksConfig> sliSmooksConfigMap) {
        this.sliSmooksConfigMap = sliSmooksConfigMap;
    }

    public void setBeanId(String beanId) {
        this.beanId = beanId;
    }

    public void setNrMongoStagingWriter(ResourceWriter<NeutralRecord> nrMongoStagingWriter) {
        this.nrMongoStagingWriter = (NeutralRecordMongoAccess) nrMongoStagingWriter;
    }
}

@@ -64,34 +64,8 @@
 on;%0A
-import java.util.HashMap;%0A
 impo
@@ -83,16 +83,16 @@
 l.List;%0A
+
 import j
@@ -801,83 +801,8 @@
 ter;
-%0A    private Map%3CString, Smooks%3E mapSmooks = new HashMap%3CString, Smooks%3E();
 %0A%0A  
@@ -1789,21 +1789,20 @@
 mooks = 
-fetch
+new 
 Smooks(s
@@ -1815,16 +1815,36 @@
 ksConfig
+.getConfigFileName()
 );%0A%0A    
@@ -2373,24 +2373,25 @@
 reIndex();%0A%0A
+%0A
             
@@ -2626,32 +2626,32 @@
     %7D%0A        %7D%0A
+
         return s
@@ -2668,744 +2668,8 @@
  %7D%0A%0A
-    /**%0A     * Returns a Smooks object for the given config, either from cache or by constructing a new%0A     * instance. Constructing smooks objects are slow, hence our use of a cache.%0A     *%0A     * @param sliSmooksConfig%0A     * @return%0A     * @throws IOException%0A     * @throws SAXException%0A     */%0A    private Smooks fetchSmooks(SliSmooksConfig sliSmooksConfig) throws IOException, SAXException %7B%0A%0A        String configName = sliSmooksConfig.getConfigFileName();%0A        Smooks inCache = mapSmooks.get(configName);%0A        if (inCache == null) %7B%0A            Smooks smooks = new Smooks(configName);%0A            mapSmooks.put(configName, smooks);%0A            return smooks;%0A        %7D else %7B%0A            return inCache;%0A        %7D%0A    %7D%0A%0A
     

Revert "Changed smooks factory to cache a smooks object per config"