FormController.java

package edu.rit.coopeval.controller;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import edu.rit.coopeval.authentication.beans.User;
import edu.rit.coopeval.dao.*;
import edu.rit.coopeval.form.FormType;
import edu.rit.coopeval.model.*;
import edu.rit.coopeval.viewmodel.evaluation.LikertScaleViewModel;
import edu.rit.coopeval.viewmodel.form.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

/**
 * Created by mhickson on 4/6/15.
 */
@RestController
@Scope("session")
@RequestMapping(value="/services/FormService")
public class FormController {
    @Autowired
    private FormRepository formRepo;
    @Autowired
    private QuestionGroupRepository questionGroupRepo;
    @Autowired
    private FormQuestionRepository formQuestionRepo;
    @Autowired
    private QuestionRepository questionRepo;
    @Autowired
    private LikertScaleRepository likertScaleRepo;
    @Autowired
    private QuestionTypeRepository questionTypeRepo;
    @Autowired
    private QuestionCatagoryRepository questionCatagoryRepo;

    @Autowired
    private DepartmentTermFormRepository departmentTermFormRepo;

    @Autowired
    private DepartmentRepository departmentRepo;

    @Autowired
    private TermRepository termRepo;

    @Autowired
    private EvaluationRepository evaluationRepo;

    private FormViewModel formViewModel;

    private List<Long> deletedQuestions;
    private List<Long> deletedQuestionGroups;

    @RequestMapping(value = "/getStudentForms", method = RequestMethod.GET)
    public List<FormSummaryViewModel> getStudentForms(){
        List<FormSummaryViewModel> forms = new ArrayList<FormSummaryViewModel>();
        for(Form form: formRepo.findByIsStudentForm("1")){
            forms.add(new FormSummaryViewModel(form, FormType.STUDENT));
        }
        return forms;
    }

    @RequestMapping(value = "/getEmployerForms", method = RequestMethod.GET)
    public List<FormSummaryViewModel> getEmployerForms(){
        List<FormSummaryViewModel> forms = new ArrayList<FormSummaryViewModel>();
        for(Form form: formRepo.findByIsStudentForm("0")){
            forms.add(new FormSummaryViewModel(form, FormType.EMPLOYER));
        }
        return forms;
    }

    @RequestMapping(value = "/getAllQuestionCategories", method = RequestMethod.GET)
    public List<String> getAllQuestionCategories(){
        List<String> categories = new ArrayList<String>();
        for(QuestionCatagory questionCategory: questionCatagoryRepo.findAll()){
            categories.add(questionCategory.getName());
        }
        return categories;
    }

    @RequestMapping(value = "/getAllQuestionTypes", method = RequestMethod.GET)
    public List<String> getAllQuestionTypes(){
        List<String> questionTypes = new ArrayList<String>();
        for(QuestionType questionType: questionTypeRepo.findAll()){
            questionTypes.add(questionType.getName());
        }
        return questionTypes;
    }

    @RequestMapping(value = "/getForm", method = RequestMethod.GET)
    public FormViewModel getForm(@RequestParam(value="name") String name) {
        this.formViewModel = new FormViewModel(formRepo.findByName(name));
        this.deletedQuestions = new ArrayList<Long>();
        this.deletedQuestionGroups = new ArrayList<Long>();
        return formViewModel;
    }

    @RequestMapping(value = "/assignForm", method = RequestMethod.PUT)
    public void assignForm(@RequestBody AssignFormCriteria assignFormCriteria) {
        DepartmentTermForm departmentTermForm = departmentTermFormRepo.findByDepartmentIdAndTermCode(assignFormCriteria.getDepartment().getDepartmentId(), assignFormCriteria.getTermCode());
        if(departmentTermForm == null){
            departmentTermForm = new DepartmentTermForm();
            departmentTermForm.setTermByTermId(termRepo.findByTermCode(assignFormCriteria.getTermCode()));
            departmentTermForm.setDepartment(departmentRepo.findOne(assignFormCriteria.getDepartment().getDepartmentId()));
        }

        if(assignFormCriteria.getIsStudentForm().equals("1")){
            departmentTermForm.setFormByStudentFormId(formRepo.findOne(assignFormCriteria.getForm().getFormId()));
        }
        else{
            departmentTermForm.setFormByEmployerFormId(formRepo.findOne(assignFormCriteria.getForm().getFormId()));
        }

        departmentTermFormRepo.save(departmentTermForm);
    }

    @RequestMapping(value = "/createForm", method = RequestMethod.PUT)
    public FormSummaryViewModel createForm(@RequestBody FormCreationViewModel formCreationViewModel, HttpSession session) throws IllegalArgumentException {
        User currentUser = (User) session.getAttribute("currentUser");
        if(formRepo.findByName(formCreationViewModel.getName()) != null){
            throw new IllegalArgumentException("Form with the same name already exists");
        }

        Form formEntity = new Form();
        if(formCreationViewModel.getIsStudentForm()){
            formEntity.setIsStudentForm("1");
        }
        else{
            formEntity.setIsStudentForm("0");
        }
        formEntity.setName(formCreationViewModel.getName());
        Form savedFormEntity = formRepo.save(formEntity);

        if(formCreationViewModel.getIsStudentForm()){
            return new FormSummaryViewModel(savedFormEntity,FormType.STUDENT);
        }
        else{
            return new FormSummaryViewModel(savedFormEntity,FormType.EMPLOYER);
        }

    }

    @RequestMapping(value = "/deleteForm", method = RequestMethod.DELETE)
    public FormSummaryViewModel deleteForm(@RequestParam Long formId, HttpServletResponse response) throws IllegalArgumentException {
        Form formEntity = formRepo.findOne(formId);
        FormSummaryViewModel formSummaryViewModel = new FormSummaryViewModel();
        if(formEntity != null && evaluationRepo.findByStudentFormId(formEntity.getFormId()).isEmpty() &&
                evaluationRepo.findByEmployerFormId(formEntity.getFormId()).isEmpty() &&
                departmentTermFormRepo.findByStudentFormId(formEntity.getFormId()).isEmpty() &&
                departmentTermFormRepo.findByEmployerFormId(formEntity.getFormId()).isEmpty()){
            if(formEntity.getIsStudentForm().equals("1")){
                formSummaryViewModel = new FormSummaryViewModel(formEntity,FormType.STUDENT);
            }
            else{
                formSummaryViewModel = new FormSummaryViewModel(formEntity,FormType.EMPLOYER);
            }
            this.deleteFromQuestionsAttachedToForm(formEntity);
            formRepo.delete(formEntity);
        }
        else{
            throw new IllegalArgumentException("Invalid Delete Request");
        }
        return formSummaryViewModel;

    }

    private void deleteFromQuestionsAttachedToForm(Form formEntity){
        List<FormQuestion> formQuestions = formQuestionRepo.findByForm(formEntity);
        Long questionId;
        Question questionEntity;
        for(FormQuestion formQuestionEntity: formQuestions){
            questionId = formQuestionEntity.getQuestionByQuestionId().getQuestionId();
            formQuestionRepo.delete(formQuestionEntity);

            questionEntity = questionRepo.findOne(questionId);
            questionRepo.delete(questionEntity);
        }
    }

    @RequestMapping(value = "/getEmptyFormQuestionGroup", method = RequestMethod.GET)
    public FormQuestionGroupViewModel getEmptyFormQuestionGroup(){
        return new FormQuestionGroupViewModel();
    }

    @RequestMapping(value = "/getEmptyFormQuestion", method = RequestMethod.GET)
    public FormQuestionViewModel getEmptyFormQuestion(){
        FormQuestionViewModel formQuestionViewModel = new FormQuestionViewModel();
        formQuestionViewModel.setIsRequired("0");
        formQuestionViewModel.setIsCommentAllowed("0");
        return formQuestionViewModel;
    }

    @RequestMapping(value = "/saveForm", method = RequestMethod.PUT)
    public void saveForm(@RequestBody FormViewModel formViewModelSave){
        Form formEntity = formRepo.findOne(formViewModelSave.getFormId());
        this.deleteQuestions(this.deletedQuestions);
        this.deleteQuestionGroup(this.deletedQuestionGroups);

        QuestionGroup questionGroupEntity;
        for(FormQuestionGroupViewModel questionGroup: formViewModelSave.getQuestionGroups()){
            questionGroupEntity = saveQuestionGroup(questionGroup);
            for(FormQuestionViewModel question: questionGroup.getQuestions()){
                this.saveFormQuestion(question,formEntity,questionGroupEntity);
            }
        }
    }

    private void deleteQuestions(List<Long> deleteIds){
        FormQuestion formQuestionEntity;
        Question questionEntity;
        for(Long id: deleteIds){
            formQuestionEntity = formQuestionRepo.findOne(id);
            if(formQuestionEntity != null){
                questionEntity = formQuestionEntity.getQuestionByQuestionId();
                formQuestionRepo.delete(formQuestionEntity);
                questionRepo.delete(questionEntity);
            }
        }
    }

    private void deleteQuestionGroup(List<Long> deleteIds){
        QuestionGroup questionGroupEntity;
        List<Long> deleteFormQuestionIds;
        for(Long id: deleteIds){
            questionGroupEntity = questionGroupRepo.findOne(id);
            if(questionGroupEntity != null){
                deleteFormQuestionIds = new ArrayList<Long>();
                for(FormQuestion formQuestionEntity : formQuestionRepo.findByQuestionGroupId(id)){
                    deleteFormQuestionIds.add(formQuestionEntity.getFormQuestionId());
                }
                deleteQuestions(deleteFormQuestionIds);
                questionGroupRepo.delete(questionGroupEntity);
            }
        }
    }

    private QuestionGroup saveQuestionGroup(FormQuestionGroupViewModel questionGroupViewModel){
        QuestionGroup questionGroupEntity;
        if(questionGroupViewModel.getQuestionGroupId() != null){
            questionGroupEntity = questionGroupRepo.findOne(questionGroupViewModel.getQuestionGroupId());
        }
        else{
            questionGroupEntity = new QuestionGroup();
        }
        questionGroupEntity.setName(questionGroupViewModel.getName());
        questionGroupEntity.setContent(questionGroupViewModel.getContent());
        questionGroupEntity.setHeader1(questionGroupViewModel.getHeader1());
        questionGroupEntity.setHeader2(questionGroupViewModel.getHeader2());
        if(questionGroupViewModel.getLikertScale1() != null){
            LikertScale likertScale1 = this.saveLikertScale(questionGroupViewModel.getLikertScale1());
            questionGroupEntity.setLikertScale1(likertScale1);
        }
        if(questionGroupViewModel.getLikertScale2() != null){
            LikertScale likertScale2 = this.saveLikertScale(questionGroupViewModel.getLikertScale1());
            questionGroupEntity.setLikertScale1(likertScale2);
        }
        return questionGroupRepo.save(questionGroupEntity);
    }

    private LikertScale saveLikertScale(LikertScaleViewModel likertScaleViewModel){
        LikertScale likertScaleEntity;
        if(likertScaleViewModel.getLikertScaleId() != null){
            likertScaleEntity = likertScaleRepo.findOne(likertScaleViewModel.getLikertScaleId());
        }
        else{
            likertScaleEntity = new LikertScale();
        }
        likertScaleEntity.setLevelOne(likertScaleViewModel.getLevelOne());
        likertScaleEntity.setLevelTwo(likertScaleViewModel.getLevelTwo());
        likertScaleEntity.setLevelThree(likertScaleViewModel.getLevelThree());
        likertScaleEntity.setLevelFour(likertScaleViewModel.getLevelFour());
        likertScaleEntity.setLevelFive(likertScaleViewModel.getLevelFive());
        return likertScaleRepo.save(likertScaleEntity);
    }

    private FormQuestion saveFormQuestion(FormQuestionViewModel formQuestionViewModel, Form form, QuestionGroup questionGroup){
        FormQuestion formQuestionEntity;
        Question questionEntity;
        if(formQuestionViewModel.getFormQuestionId() != null){
            formQuestionEntity = formQuestionRepo.findOne(formQuestionViewModel.getFormQuestionId());
            questionEntity = formQuestionEntity.getQuestionByQuestionId();
        }
        else{
            formQuestionEntity = new FormQuestion();
            questionEntity = new Question();
        }
        questionEntity.setText(formQuestionViewModel.getText());
        questionEntity.setHelpText(formQuestionViewModel.getHelpText());
        QuestionCatagory questionCategory = questionCatagoryRepo.findByName(formQuestionViewModel.getCategory());
        QuestionType questionType = questionTypeRepo.findByName(formQuestionViewModel.getQuestionType());
        if(questionCategory != null){
            questionEntity.setQuestionCatagoryByQuestionCatagoryId(questionCategory);
        }
        else{
            questionCategory = new QuestionCatagory();
            questionCategory.setName(formQuestionViewModel.getCategory());
            questionCategory = questionCatagoryRepo.save(questionCategory);
            questionEntity.setQuestionCatagoryByQuestionCatagoryId(questionCategory);
        }
        if(questionType != null){
            questionEntity.setQuestionTypeByQuestionTypeId(questionType);
        }
        questionEntity = questionRepo.save(questionEntity);

        formQuestionEntity.setFormByFormId(form);
        formQuestionEntity.setQuestionByQuestionId(questionEntity);
        formQuestionEntity.setQuestionOrder(formQuestionViewModel.getQuestionOrder());
        formQuestionEntity.setQuestionGroupByQuestionQuestionId(questionGroup);
        formQuestionEntity.setIsCommentAllowed(formQuestionViewModel.getIsCommentAllowed());
        formQuestionEntity.setIsRequired(formQuestionViewModel.getIsRequired());
        return formQuestionRepo.save(formQuestionEntity);

    }

    private long getNewQuestionOrderNum(FormQuestionGroupViewModel currentQuestionGroup, FormQuestionGroupViewModel previousQuestionGroup) {
        List<FormQuestionViewModel> questions = currentQuestionGroup.getQuestions();
        long newQuestionOrderNum = 0;
        if (!questions.isEmpty()) {
            newQuestionOrderNum = (questions.get(questions.size() - 1).getQuestionOrder()) + 1;
        } else if(previousQuestionGroup != null && questions.isEmpty()) {
            List<FormQuestionViewModel> previousQuestions = previousQuestionGroup.getQuestions();
            newQuestionOrderNum = previousQuestions.get(previousQuestions.size() - 1).getQuestionOrder() + 1;
        }
        return newQuestionOrderNum;
    }

    @ExceptionHandler({IllegalArgumentException.class})
    void handleBadRequests(HttpServletResponse response) throws IOException {
        response.sendError(HttpStatus.BAD_REQUEST.value());
    }
}