package org.slc.sli.ingestion.xml.idref;

import java.util.concurrent.Callable;

import org.slc.sli.ingestion.BatchJobStageType;
import org.slc.sli.ingestion.Fault;
import org.slc.sli.ingestion.FaultType;
import org.slc.sli.ingestion.Job;
import org.slc.sli.ingestion.landingzone.IngestionFileEntry;
import org.slc.sli.ingestion.model.Error;
import org.slc.sli.ingestion.model.da.BatchJobDAO;
import org.slc.sli.ingestion.validation.ErrorReport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * Id Reference Resolution of the future...
 *
 * @author shalka
 */
@Scope("prototype")
@Component
public class IdRefResolutionCallable implements Callable<Boolean> {

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

    private final IdRefResolutionHandler resolver;
    private final IngestionFileEntry entry;
    private final Job job;
    private final BatchJobDAO batchJobDao;

    /**
     * Default constructor for the id reference resolution callable.
     *
     * @param fileEntry
     *            ingestion file entry.
     * @param job
     *            batch job.
     * @param handler
     *            IdRefResolutionHandler to resolve references in ingestion file entries.
     */
    public IdRefResolutionCallable(IdRefResolutionHandler resolver, IngestionFileEntry fileEntry, Job job,
            BatchJobDAO batchJobDao) {
        this.resolver = resolver;
        this.entry = fileEntry;
        this.job = job;
        this.batchJobDao = batchJobDao;
    }

    /**
     * Entry point of IdRefResolutionCallable.
     */
    @Override
    public Boolean call() throws Exception {
        LOG.info("Starting IdRefResolutionCallable for: " + entry.getFileName());
        IngestionFileEntry fileEntry = processResolution(entry, entry.getErrorReport());
        boolean hasErrors = aggregateAndLogResolutionErrors(fileEntry);
        LOG.info("Finished IdRefResolutionCallable for: " + entry.getFileName());
        return hasErrors;
    }

    /**
     * Process id reference resolution using the specified handler.
     *
     * @param fileEntry
     *            ingestion file entry.
     * @param errorReport
     *            error report.
     * @return ingestion file entry (contains faults and errors).
     */
    private IngestionFileEntry processResolution(IngestionFileEntry fileEntry, ErrorReport errorReport) {
        return resolver.handle(fileEntry, errorReport);
    }

    /**
     * Logs errors incurred during id reference resolution.
     *
     * @param fileEntry
     *            ingestion file entry.
     * @return integer representing number of errors during id reference resolution.
     */
    private boolean aggregateAndLogResolutionErrors(IngestionFileEntry fileEntry) {
        int errorCount = 0;
        for (Fault fault : fileEntry.getFaultsReport().getFaults()) {
            String faultMessage = fault.getMessage();
            String faultLevel = fault.isError() ? FaultType.TYPE_ERROR.getName()
                    : fault.isWarning() ? FaultType.TYPE_WARNING.getName() : "Unknown";

            Error error = Error.createIngestionError(job.getId(), fileEntry.getFileName(),
                    BatchJobStageType.XML_FILE_PROCESSOR.getName(), null, null, null, faultLevel, faultLevel,
                    faultMessage);
            batchJobDao.saveError(error);

            if (fault.isError()) {
                errorCount++;
            }
        }
        return errorCount > 0;
    }
}

@@ -401,62 +401,8 @@
 O;%0D%0A
-import org.slc.sli.ingestion.validation.ErrorReport;%0D%0A
 impo
@@ -1838,24 +1838,26 @@
 me());%0D%0A
+%0D%0A
         
 Ingestio
@@ -1852,56 +1852,23 @@
     
-IngestionFileEntry fileEntry = processResolution
+resolver.handle
 (ent
@@ -1893,24 +1893,26 @@
 Report());%0D%0A
+%0D%0A
         bool
@@ -1963,21 +1963,17 @@
 ors(
-fileE
+e
 ntry);%0D%0A
     
@@ -1964,24 +1964,26 @@
 rs(entry);%0D%0A
+%0D%0A
         LOG.
@@ -2093,469 +2093,8 @@
 %0D%0A%0D%0A
-    /**%0D%0A     * Process id reference resolution using the specified handler.%0D%0A     *%0D%0A     * @param fileEntry%0D%0A     *            ingestion file entry.%0D%0A     * @param errorReport%0D%0A     *            error report.%0D%0A     * @return ingestion file entry (contains faults and errors).%0D%0A     */%0D%0A    private IngestionFileEntry processResolution(IngestionFileEntry fileEntry, ErrorReport errorReport) %7B%0D%0A        return resolver.handle(fileEntry, errorReport);%0D%0A    %7D%0D%0A%0D%0A
     

fix bug - when idrefhandler fails, the IngestionFileEntry it returns is null. we can just use the object we passed in since it's by reference.