package org.appfuse.webapp.action;

import java.util.List;

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

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.appfuse.Constants;
import org.appfuse.model.Resume;
import org.appfuse.model.User;
import org.appfuse.service.ResumeManager;
import org.appfuse.webapp.form.ResumeForm;


/**
 * Implementation of <strong>Action</strong> that interacts with the {@link
 * ResumeForm} and retrieves values.  It interacts with the {@link
 * ResumeManager} to retrieve/persist values to the database.
 *
 * <p>
 * <a href="ResumeAction.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author <a href="mailto:[email protected]">Matt Raible</a>
 * @version $Revision: 1.10 $ $Date: 2004/04/01 22:33:44 $
 *
 * @struts.action name="resumeForm" path="/viewResumes" scope="request"
 *  validate="false" parameter="action" input="mainMenu"
 * @struts.action name="resumeForm" path="/editResume" scope="request"
 *  validate="false" parameter="action" input="mainMenu"
 * @struts.action name="resumeForm" path="/saveResume" scope="request"
 *  validate="true" parameter="action" input="edit"
 *
 * @struts.action-forward name="edit" path=".resumeDetail"
 * @struts.action-forward name="list" path=".resumeList"
 * @struts.action-forward name="comments" path=".additionalInformation"
 * @struts.action-forward name="continue" path="/schools.do"
 * @struts.action-forward name="finish" path="/finishingUp.do"
 */
public final class ResumeAction extends BaseAction {
    /** The <code>Log</code> instance for this class */
    private Log log = LogFactory.getLog(ResumeAction.class);

    public ActionForward cancel(ActionMapping mapping, ActionForm form,
                                HttpServletRequest request,
                                HttpServletResponse response)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Entering 'cancel' method");
        }

        // return a forward to edit forward
        return mapping.findForward("viewResumes");
    }

    public ActionForward edit(ActionMapping mapping, ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Entering 'edit' method");
        }

        ResumeForm resumeForm = (ResumeForm) form;
        ResumeManager mgr = (ResumeManager) getBean("resumeManager");
        User user = getUser(request.getSession());
        String userId = user.getId().toString();
        List resumes = mgr.getResumesForUser(userId);

        if ((resumes == null) || (resumes.size() == 0)) {
            if (log.isDebugEnabled()) {
                log.debug("No resumes found for user: " + user.getUsername());
                log.debug("Adding a new one...");
            }
            resumeForm.setUserId(userId);
            Resume resume = (Resume) mgr.saveResume(convert(resumeForm));
            updateFormBean(mapping, request, convert(resume));
        } else {
            // grab the first resume and stuff it in the request
            updateFormBean(mapping, request, resumes.get(0));
            
            if ("additional".equals(request.getParameter("show"))) {
                return mapping.findForward("comments");
            }
        }

        // return a forward to edit forward
        return mapping.findForward("edit");
    }

    public ActionForward delete(ActionMapping mapping, ActionForm form,
                                HttpServletRequest request,
                                HttpServletResponse response)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Entering 'delete' method");
        }

        // Extract attributes and parameters we will need
        ActionMessages messages = new ActionMessages();

        ResumeForm resumeForm = (ResumeForm) form;

        try {
            ResumeManager mgr = (ResumeManager) getBean("resumeManager");
            mgr.removeObject(convert(resumeForm));
        } catch (Exception e) {
            e.printStackTrace();

            ActionErrors errors = new ActionErrors();

            errors.add(ActionErrors.GLOBAL_ERROR,
                       new ActionError("errors.general"));

            StringBuffer sb = new StringBuffer();

            if (e.getCause() == null) {
                sb.append(e.getMessage());
            } else {
                while (e.getCause() != null) {
                    sb.append(e.getMessage());

                    sb.append("\n");

                    e = (Exception) e.getCause();
                }
            }

            errors.add(ActionErrors.GLOBAL_ERROR,
                       new ActionError("errors.detail", sb.toString()));

            saveErrors(request, errors);

            return mapping.getInputForward();
        }

        messages.add(ActionMessages.GLOBAL_MESSAGE,
                     new ActionMessage("resume.deleted"));

        request.getSession().setAttribute(Globals.MESSAGE_KEY, messages);

        // return a forward to list
        return mapping.findForward("mainMenu");
    }

    public ActionForward nextPage(ActionMapping mapping, ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Entering 'nextPage' method");
            log.debug("Step 1: calling save method");
        }

        save(mapping, form, request, response);

        getMessages(request);

        String next = null;
        if ("additionalInformation".equals(request.getParameter("from"))) {
            next = mapping.findForward("finish").getPath();
            request.setAttribute("menuUrl", "finishingUp.do");
        } else {
            next = mapping.findForward("continue").getPath();
            request.setAttribute("menuUrl", "generalInformation.do");
        }
        
        if (log.isDebugEnabled()) {
            log.debug("Step 2: forwarding to '" + next + "'");
        }

        // true signifies a redirect
        return new ActionForward(next, true);
    }

    public ActionForward save(ActionMapping mapping, ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Entering 'save' method");
        }

        // Extract attributes and parameters we will need
        ResumeForm resumeForm = (ResumeForm) form;
        boolean isNew = StringUtils.equals(request.getParameter("new"), "true");
        HttpSession session = request.getSession();

        // set the userId if it's not set
        if (resumeForm.getUserId().equals("")) {
            resumeForm.setUserId(getUser(session).getId().toString());
        }

        if (isNew) {
            resumeForm.setId(null);
        }

        try {
            ResumeForm save = new ResumeForm();
            BeanUtils.copyProperties(save, resumeForm);

            ResumeManager mgr = (ResumeManager) getBean("resumeManager");
            mgr.saveResume(convert(save));
        } catch (Exception e) {
            e.printStackTrace();

            ActionErrors errors = new ActionErrors();

            errors.add(ActionErrors.GLOBAL_ERROR,
                       new ActionError("errors.general"));

            StringBuffer sb = new StringBuffer();

            if (e.getCause() == null) {
                sb.append(e.getMessage());
            } else {
                while (e.getCause() != null) {
                    sb.append(e.getMessage());

                    sb.append("\n");

                    e = (Exception) e.getCause();
                }
            }

            errors.add(ActionErrors.GLOBAL_ERROR,
                       new ActionError("errors.detail", sb.toString()));

            saveErrors(request, errors);

            return mapping.getInputForward();
        }

        ActionMessages messages = new ActionMessages();

        if (isNew) {
            messages.add(ActionMessages.GLOBAL_MESSAGE,
                         new ActionMessage("resume.added", resumeForm.getName()));
        } else {
            messages.add(ActionMessages.GLOBAL_MESSAGE,
                         new ActionMessage("resume.updated"));
        }
        
        saveMessages(request, messages);

        if (log.isDebugEnabled()) {
            log.debug("forwarding to edit resume...");
        }
        // set flag so menu knows which item to highlight
        request.setAttribute("menuUrl", "editResume.do");

        return mapping.findForward("edit");
    }

    public ActionForward search(ActionMapping mapping, ActionForm form,
                                HttpServletRequest request,
                                HttpServletResponse response)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Entering 'search' method");
        }

        HttpSession session = request.getSession(false);

        ResumeManager mgr = (ResumeManager) getBean("resumeManager");

        // getUserForm() is a method in BaseAction
        List userResumes = 
            mgr.getResumesForUser(getUser(session).getId().toString());

        request.setAttribute(Constants.USER_RESUMES, userResumes);

        // forward to action-forward defined using XDoclet at
        // the beginning of this class
        return mapping.findForward("list");
    }
}