/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/

package gov.va.med.esr.common.report.data;

import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.Validate;

import gov.va.med.esr.common.model.lookup.ReportEEDWeeklyType;
import gov.va.med.esr.common.model.lookup.StandardReport;
import gov.va.med.esr.common.model.report.ReportEEDWeeklyReportType;
import gov.va.med.esr.common.model.report.ReportParameterSet;
import gov.va.med.esr.common.model.report.ReportSetup;
import gov.va.med.esr.common.model.security.ESRUserPrincipal;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.StandardReportService;
import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.fw.report.ReportExportedType;
import gov.va.med.fw.scheduling.AbstractScheduledProcess;
import gov.va.med.fw.scheduling.ScheduledProcessInvocationContext;
import gov.va.med.fw.security.SecurityContextHelper;
import gov.va.med.fw.security.UserPrincipal;
import gov.va.med.fw.util.DateUtils;

/**
 * @author DNS   LEV
 *
 */
public class WeeklyReportScheduledProcess extends AbstractScheduledProcess {

   /**
    * An instance of lookupService
    */
   private LookupService lookupService = null;
   
   /**
    * An instance of standardReportService
    */
   private StandardReportService standardReportService = null;
   
   /**
    * A default constructor 
    */
   public WeeklyReportScheduledProcess() {
      super();
   }

   public void afterPropertiesSet() {
      super.afterPropertiesSet();
      Validate.notNull( this.lookupService, "A lookup service is required" );
      Validate.notNull( this.standardReportService, "A standard report service is required" );
   }

   public void setLookupService(LookupService lookupService) {
      this.lookupService = lookupService;
   }

   public void setStandardReportService(StandardReportService service) {
      this.standardReportService = service;
   }

   protected StandardReport getStandadReport( String code ) throws UnknownLookupTypeException, UnknownLookupCodeException {
      return this.lookupService.getStandardReportByCode( code );
   }
   
   protected ReportExportedType getReportExportedType( String code ) throws UnknownLookupTypeException, UnknownLookupCodeException {
      return this.lookupService.getReportExportedTypeByCode( code ); 
   }
   
   protected void generateReport( UserPrincipal user, ReportSetup setup ) throws Exception {
      this.standardReportService.generateReport( user, setup );
   }
   
   /**
    * @see gov.va.med.fw.scheduling.AbstractScheduledProcess#executeProcess(java.lang.Object)
    */
   protected void executeProcess(ScheduledProcessInvocationContext context) throws Exception {
      
      // Set date is the begining of a fiscal year
      Date startTime = DateUtils.getFiscalYearFirstQuarter( DateUtils.getFiscalYear( DateUtils.getCurrentDate() ), true ).getTime();
      
      // Set end date to the begining of the week so that a report will compute on the preceeding week's data
      Calendar calendar = Calendar.getInstance();
      int dayOfWeek = calendar.get( Calendar.DAY_OF_WEEK );
      dayOfWeek = (dayOfWeek != Calendar.SUNDAY) ? Calendar.SUNDAY : dayOfWeek;
      calendar.set( Calendar.DAY_OF_WEEK, dayOfWeek );
      Date endTime = calendar.getTime();
      
      // Create report parameter set
      ReportParameterSet parameterSet = new ReportParameterSet();
      parameterSet.setFileType( this.getReportExportedType( ReportExportedType.PDF.getName() ) );
      parameterSet.setFromDate( startTime );
      parameterSet.setToDate( endTime );
      
      // Add OTHER_UPDATES report
      ReportEEDWeeklyReportType type = new ReportEEDWeeklyReportType();
      type.setReportEEDWeeklyType( this.lookupService.getReportEEDWeeklyTypeByCode(ReportEEDWeeklyType.OTHER_UPDATES.getCode()) );
      parameterSet.addReportEEDWeeklyReportType( type );
      
      // Add AAC_ADDRESS_STATS report
      type = new ReportEEDWeeklyReportType();
      type.setReportEEDWeeklyType( this.lookupService.getReportEEDWeeklyTypeByCode(ReportEEDWeeklyType.AAC_ADDRESS_STATS.getCode()) );
      parameterSet.addReportEEDWeeklyReportType( type );
      
      // Add AAC_AUTO_UDPATE report
      type = new ReportEEDWeeklyReportType();
      type.setReportEEDWeeklyType( this.lookupService.getReportEEDWeeklyTypeByCode(ReportEEDWeeklyType.AAC_AUTO_UDPATE.getCode()) );
      parameterSet.addReportEEDWeeklyReportType( type );
      
      // Add ENROLLMENT_UPDATES report
      type = new ReportEEDWeeklyReportType();
      type.setReportEEDWeeklyType( this.lookupService.getReportEEDWeeklyTypeByCode(ReportEEDWeeklyType.ENROLLMENT_UPDATES.getCode()) );
      parameterSet.addReportEEDWeeklyReportType( type );
      
      // Add ENROLLMENT_UPDATES report
      type = new ReportEEDWeeklyReportType();
      type.setReportEEDWeeklyType( this.lookupService.getReportEEDWeeklyTypeByCode(ReportEEDWeeklyType.AAC_ENROLLMENT_LETTERS.getCode()) );
      parameterSet.addReportEEDWeeklyReportType( type );

      type = new ReportEEDWeeklyReportType();
      type.setReportEEDWeeklyType( this.lookupService.getReportEEDWeeklyTypeByCode(ReportEEDWeeklyType.ELIGIBILITY_UPDATES.getCode()) );
      parameterSet.addReportEEDWeeklyReportType( type );
      type = new ReportEEDWeeklyReportType();
      type.setReportEEDWeeklyType( this.lookupService.getReportEEDWeeklyTypeByCode(ReportEEDWeeklyType.PH_STATS.getCode()) );
      parameterSet.addReportEEDWeeklyReportType( type );
      
      
      // Create a report setup
      ReportSetup setup = new ReportSetup();
      setup.setReport( this.getStandadReport( StandardReport.CODE_EED_8.getCode() ) );
      setup.setParameterSet( parameterSet );
      
      UserPrincipal user = SecurityContextHelper.getSecurityContext().getUserPrincipal();
      
      setup.setSetupUser( user instanceof ESRUserPrincipal ? (ESRUserPrincipal)user : null );

      this.generateReport( user, setup );
   }
}