/*
 * Copyright 2012-2013 inBloom, Inc. and its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.slc.sli.bulk.extract.context.resolver.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import org.slc.sli.bulk.extract.context.resolver.ContextResolver;
import org.slc.sli.domain.Entity;
import org.slc.sli.domain.Repository;

/**
 * Context resolver for students
 * 
 * @author nbrown
 * 
 */
@Component
public class StudentContextResolver implements ContextResolver {
    private static final Logger LOG = LoggerFactory.getLogger(StudentContextResolver.class);
    
    @Autowired
    @Qualifier("secondaryRepo")
    private Repository<Entity> repo;
    
    @Override
    public Set<String> findGoverningLEA(Entity entity) {
        Set<String> leas = new HashSet<String>();
        List<Map<String, Object>> schools = entity.getDenormalizedData().get("schools");
        for (Map<String, Object> school : schools) {
            try {
                String startDate = (String) school.get("entryDate");
                String exitDate = (String) school.get("exitWithdrawDate");
                boolean afterStart = startDate == null
                        || !ISODateTimeFormat.date().parseDateTime(startDate).isAfterNow();
                boolean beforeFinish = exitDate == null
                        || !ISODateTimeFormat.date().parseDateTime(exitDate).isBeforeNow();
                if (afterStart && beforeFinish) {
                    @SuppressWarnings("unchecked")
                    List<String> edOrgs = (List<String>) school.get("edOrgs");
                    for (String edOrg : edOrgs) {
                        leas.add(edOrg);
                    }
                }
            } catch (RuntimeException e) {
                LOG.warn("Could not parse school " + school, e);
            }
        }
        return leas;
    }
    
    /**
     * Find the LEAs based on a given student id
     * Will use local cache if available, otherwise will pull student from Mongo
     * 
     * @param id
     *            the ID of the student
     * @return the set of LEAs
     */
    public Set<String> getLEAsForStudentId(String id) {
        Entity entity = getRepo().findById("student", id);
        if (entity != null) {
            return findGoverningLEA(entity);
        }
        return new HashSet<String>();
    }
    
    Repository<Entity> getRepo() {
        return repo;
    }
    
    void setRepo(Repository<Entity> repo) {
        this.repo = repo;
    }
    
}

@@ -1812,61 +1812,88 @@
     
-String startDate = (String) school.get(%22entryDate%22);%0A
+if (isCurrent(school)) %7B%0A                    @SuppressWarnings(%22unchecked%22)%0A    
     
@@ -1908,33 +1908,43 @@
     
+List%3C
 String
+%3E
  e
-xitDate = (
+dOrgs = (List%3C
 String
+%3E
 ) sc
@@ -1958,23 +1958,13 @@
 t(%22e
-xitWithdrawDate
+dOrgs
 %22);%0A
@@ -1983,195 +1983,109 @@
     
-boolean afterStart = startDate == null%0A                        %7C%7C !ISODateTimeFormat.date().parseDateTime(startDate).isAfterNow();%0A                boolean beforeFinish = exitDate == null%0A
+    for (String edOrg : edOrgs) %7B%0A                        leas.add(edOrg);%0A                    %7D%0A    
     
@@ -2084,32 +2084,34 @@
                 
+%7D%0A
             %7C%7C !
@@ -2110,125 +2110,103 @@
     
-%7C%7C !ISODateTimeFormat.date().parseDateTime(exitDate).isBeforeNow();%0A                if (afterStart && beforeFinish) %7B
+%7D catch (RuntimeException e) %7B%0A                LOG.warn(%22Could not parse school %22 + school, e);
 %0A   
@@ -2210,32 +2210,34 @@
             
+%7D%0A
         
 @SuppressWar
@@ -2228,173 +2228,209 @@
     
-@SuppressWarnings(%22unchecked%22)
+%7D%0A        return leas;
 %0A    
+%7D%0A
     
-  
+%0A
     
+/**%0A
      
- List%3CString%3E edOrgs = (List%3CString%3E) school.get(%22edOrgs%22);%0A         
+* Determine if a school association is 'current', meaning is has already started but has not%0A     * finished%0A
      
+*%0A
      
- for (String edOrg : edOrgs) %7B
+* @param schoolAssociation
 %0A     
+*
     
@@ -2441,223 +2441,634 @@
     
-       leas.add(edOrg);%0A                    %7D%0A                %7D%0A            %7D catch (RuntimeException e) %7B%0A                LOG.warn(%22Could not parse school %22 + school, e);%0A            %7D%0A        %7D%0A        return leas
+the school association to evaluate%0A     * @return true iff the school association is current%0A     */%0A    private boolean isCurrent(Map%3CString, Object%3E schoolAssociation) %7B%0A        String startDate = (String) schoolAssociation.get(%22entryDate%22);%0A        String exitDate = (String) schoolAssociation.get(%22exitWithdrawDate%22);%0A        boolean afterStart = startDate == null%0A                %7C%7C !ISODateTimeFormat.date().parseDateTime(startDate).isAfterNow();%0A        boolean beforeFinish = exitDate == null%0A                %7C%7C !ISODateTimeFormat.date().parseDateTime(exitDate).isBeforeNow();%0A        return afterStart && beforeFinish
 ;%0A  

refactor out isCurrent method