package com.k_int.discover.update;

import com.k_int.discover.datamodel.CultureGrid_BaseHDO;
import com.k_int.discover.datamodel.CultureGrid_InstitutionHDO;
import com.k_int.discover.datamodel.updates.UpdateRequestHDO;
import com.k_int.discover.datamodel.updates.UpdateStatusEnum;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
//import java.util.Locale;
//import java.util.MissingResourceException;
//import java.util.ResourceBundle;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * A class to allow the submission of general update requests to the CG system
 *
 * @author rpb rich@k-int.com
 * @version 1.0 08.02.11
 */
public class GeneralRequestUpdateAction extends ActionSupport implements ServletRequestAware, ApplicationContextAware {
	private static final long serialVersionUID = 4627804852531413021L;

	private static Log log = LogFactory.getLog(GeneralRequestUpdateAction.class);

    private HttpServletRequest request;
    private ApplicationContext ctx;
    private SessionFactory factory;
    
    public void setServletRequest(HttpServletRequest request) { this.request = request; }
    public void setApplicationContext(ApplicationContext ctx) {	this.ctx = ctx; }
    public void setSessionFactory(SessionFactory factory) { this.factory = factory; }

    public UpdateRequestResponse updateResponse = null;
    
    public UpdateRequestResponse getUpdateResponse() { return this.updateResponse; }

    private String updateInfo = null;
    private String name = null;
    private String email = null;

    public String getUpdateInfo() { return this.updateInfo; }
    public void setUpdateInfo(String updateInfo) { this.updateInfo = updateInfo; }
    public String getName() { return this.name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return this.email; }
    public void setEmail(String email) { this.email = email; }

    @Override
    public String execute() {
        log.debug("In the general request update action execute method. name: " + this.name + " email: " + this.email + " updateInfo: " + updateInfo);
        String returnValue = "xml";

        // Get all of the information from the call
        String tempInstIdentifier = request.getParameter("id");
        String format = request.getParameter("format");
        if ( format != null ) {
            if ( "json".equals(format.trim()) ) {
                returnValue = "json";
            } else if ( "xml".equals(format.trim()) ) {
                returnValue = "xml";
            }
        }
        log.debug("identifier: " + tempInstIdentifier + " format: " + format);

        // Get the allowable update range from config
//        ResourceBundle bundle = null;
//	try {
//            bundle = ResourceBundle.getBundle("updateService", Locale.getDefault());
//	} catch (MissingResourceException mre) {
//	    //leave null and use defaults.
//	}

        if ( tempInstIdentifier == null || "".equals(tempInstIdentifier.trim())
                || this.updateInfo == null || "".equals(this.updateInfo.trim())
                || ( (this.name == null || "".equals(this.name.trim()) ) && (this.email == null || "".equals(this.email.trim())) ) ) {
            // Don't have all of the information we need - can't do anything
            UpdateRequestResponse tempResp = new UpdateRequestResponse();
            tempResp.setSuccessful(false);
            tempResp.setRequestStatus(null);
            tempResp.setMessage("Unable to submit the update request as not all of the required information was provided - Posted information must include updateInfo *and* name or email");

            this.updateResponse = tempResp;
        } else {
            // We have at least a value specified for everything we need - now check they are valid
            try {
                Long recIdentifier = Long.parseLong(tempInstIdentifier);

                // Go and get the current institution record from the database
                Session sess = null;
                Transaction tx = null;
                
                try {
                    sess = factory.openSession();
                    tx = sess.beginTransaction();
                    
                    CultureGrid_BaseHDO baseHDO = CultureGrid_BaseHDO.lookupByResourceId(sess, recIdentifier);
                    if ( baseHDO != null ) {
                        // We have a record - is it an institution?
                        if ( baseHDO instanceof CultureGrid_InstitutionHDO ) {
                            // It is an institution - OK to continue
                            CultureGrid_InstitutionHDO instHDO = (CultureGrid_InstitutionHDO)baseHDO;
                            
                            Date updateTime = new Date();
                            UpdateRequestHDO updateRequest = new UpdateRequestHDO();
                            updateRequest.setEmail(this.email);
                            updateRequest.setName(this.name);
                            updateRequest.setResourceToUpdate(instHDO.getResource());
                            updateRequest.setSubmittedDate(updateTime);
                            updateRequest.setRequestStatus(UpdateStatusEnum.SUBMITTED);
                            updateRequest.setUpdateRequest(this.updateInfo.trim());

                            log.debug("Saving the general update request for later acceptance");
                            sess.save(updateRequest);
                            tx.commit();

                            UpdateRequestResponse tempResp = new UpdateRequestResponse();
                            tempResp.setSuccessful(true);
                            tempResp.setRequestStatus(UpdateStatusEnum.SUBMITTED);
                            tempResp.setMessage("Update request submitted successfully and awaiting confirmation and acceptance");
                                    
                            this.updateResponse = tempResp;
 
                        } else {
                            // Not an institution - currently not supported!
                            log.debug("The specified identifier relates to a record that exists, but isn't an institution - not currently able to update");
                            UpdateRequestResponse tempResp = new UpdateRequestResponse();
                            tempResp.setSuccessful(false);
                            tempResp.setMessage("Unable to update the specified record");
                            tempResp.setRequestStatus(null);
                            this.updateResponse = tempResp;
                        }
                    } else {
                        log.debug("No institution with the specified identifier - unable to update it!");

                        UpdateRequestResponse tempResp = new UpdateRequestResponse();
                        tempResp.setSuccessful(false);
                        tempResp.setMessage("Unable to identify the record to be updated - no update can be performed");
                        tempResp.setRequestStatus(null);
                        this.updateResponse = tempResp;
                    }

                } catch (HibernateException he) {
                    log.error("HibernateException thrown when attempting to update an institution's location: " + he.getMessage());
                    he.printStackTrace();

                    if ( tx != null ) {
                        tx.rollback();
                    }
                } finally {
                    if ( sess != null && sess.isOpen()  ) {
                        try {
                            sess.close();
                        } catch (Exception e) {
                            log.error("Exception thrown when closing the session!");
                        }
                    }
                }

            } catch (NumberFormatException nfe) {
                // Unable to parse the values into long's - therefore not valid
                log.debug("Exception thrown when parsing the passed information into doubles.. Unable to continue");

                UpdateRequestResponse tempResp = new UpdateRequestResponse();
                tempResp.setSuccessful(false);
                tempResp.setRequestStatus(null);
                tempResp.setMessage("Unable to update the record as the information passed could not be parsed");
                this.updateResponse = tempResp;
            }

        }

        // If we haven't worked out a response yet then add in a generic one
        if ( this.updateResponse == null ) {
            UpdateRequestResponse tempResp = new UpdateRequestResponse();
            tempResp.setSuccessful(false);
            tempResp.setRequestStatus(null);
            tempResp.setMessage("An unexpected error occurred when processing the update request");

            this.updateResponse = tempResp;
        }

        request.setAttribute("updateResponse", this.updateResponse);
        
        return returnValue;
    }

    
}
