/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.ui.admin.action;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.StringUtils;

import gov.va.med.esr.common.model.system.SystemParameter;
import gov.va.med.esr.common.model.lookup.Capability;
import gov.va.med.esr.common.model.lookup.SystemParameterUnit;

import gov.va.med.esr.service.SystemParameterService;

import gov.va.med.esr.ui.common.action.AbstractAction;

/**
 * @author DNS   KATIKM
 */
public class SystemParametersAction extends AbstractAction {

    public static final String SYSTEM_PARAMETERS = "systemParameters";
    
    public ActionForward display(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        SystemParametersForm sysParForm = (SystemParametersForm) form;
        SystemParameterService systemParameterService = getSystemParameterService();

        //Retrive all system parameters and display
        List systemParameters = null;
        systemParameters = systemParameterService.findAll();

        // Get the ESR Version
        String esrVersion = systemParameterService.getEsrVersion();

        // Convert the system parameters
        if (systemParameters != null && systemParameters.size() > 0)
        {
            //Sort the collection
            Collections.sort(systemParameters);

            //convert the list
            sysParForm.reset(mapping,request);
            convert(systemParameters,sysParForm);            
        }

        // Store the ESR Version
        sysParForm.setEsrVersion(esrVersion);

        return mapping.findForward(SYSTEM_PARAMETERS);
    }

    public ActionForward cancel(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        return mapping.findForward(FWD_CANCEL);
    }
    public ActionForward reset(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        return display(mapping, form, request, response); 
    }
    
    public ActionForward update(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        SystemParametersForm sysParForm;
        sysParForm = (SystemParametersForm)form;
        
        //Retrive all system parameters and display
        List systemParameters = null;
        systemParameters = getSystemParameterService().findAll();
        
        //update system parameter values        
        convert(sysParForm,systemParameters);
        
        Set updatedParameters = new HashSet();
        updatedParameters.addAll(systemParameters);
        
        //Call the service to update
        getSystemParameterService().save(updatedParameters);
        
        return mapping.findForward(FWD_DISPLAY_UPDATE_MSG);  
    }
    
    private void convert(List systemParameters, SystemParametersForm form)
    {
    	Set grantedPermissions = new HashSet(getGrantedPermissions());
    	Map requiredPermissions = SystemParameter.getCapabilityMap();
    	boolean sysAdmin = false;
    	//Only the User with System Administrator role can edit the parameters
    	if (grantedPermissions.contains(Capability.SYSTEM_ADMINISTRATOR.getCode())){
    		sysAdmin = true;
    	}

    	
        for (int i=0; i<systemParameters.size(); i++) {
            SystemParameter sysPar = (SystemParameter)systemParameters.get(i);
            String code = (String) requiredPermissions.get(sysPar.getName());
            if (sysAdmin && (code == null || grantedPermissions.contains(code))) {
            	form.add(sysPar,Boolean.TRUE); //Editable
            }
            else 
            	form.add(sysPar,Boolean.FALSE);	//Read only
        }
    }
    
    private void convert(SystemParametersForm form, List systemParameters) throws ServiceException
    {
        //make a map to access the system parameters by the name
        Map map = new HashMap();
        for (int i=0; i<systemParameters.size(); i++) {
            SystemParameter sysPar = (SystemParameter)systemParameters.get(i);
            map.put(sysPar.getName(),sysPar);
        }
        
        for (int i=0; i<systemParameters.size(); i++) {
            //get the id
            String name = form.getName(i);
            //get the target system parameter
            SystemParameter target = (SystemParameter)map.get(name);
            
            if (target == null) {
                throw new ServiceException("System Parameter Not found to update " + name);
            }
            //update units for 
            String targetUnit = target.getUnit() == null ? "" : target.getUnit().getCode();
            String sourceUnit = form.getUnit(i);
            if (!StringUtils.equals(targetUnit,sourceUnit)) {
                SystemParameterUnit unit;
                try {
                    unit = (SystemParameterUnit) getLookupCacheService().getByCodeFromCache(
                            SystemParameterUnit.class,sourceUnit);
                    target.setUnit(unit);
                } catch (Exception e) {
                    throw new ServiceException("Lookup Failed: " + e.getMessage(),e);
                }                 
            }
            //copy the value of changed
            String targetValue = target.getValue();
            String sourceValue = form.getValue(i);
            if (!targetValue.equals(sourceValue)) {
                //Value is modified
                target.setValue(sourceValue);
            }
        }
    } 
    
    public void afterPropertiesSet() throws Exception
    {
        // Nothing to do        
    }

    protected Map getKeyMethodMap()
    {
        Map map = new HashMap();
        map.put("button.update", "update");
        map.put("button.cancel", "cancel");
        map.put("button.reset", "reset");
        map.put("button.display", "display");
        return map;
    }
}
