package performa.form;

import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.logging.*;
import oneit.objstore.*;
import oneit.objstore.parser.BusinessObjectParser;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.servlets.forms.*;
import oneit.servlets.process.*;
import oneit.utils.*;
import oneit.utils.parsers.FieldException;
import performa.orm.*;
import performa.orm.types.ApplicationStatus;
import performa.utils.AnalysisEngine;
 

public class CompleteApplicationFP extends SaveFP
{
    @Override
    public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException 
    {
        HttpServletRequest  request         =   submission.getRequest();
        ObjectTransaction   objTran         =   process.getTransaction();
        JobApplication      jobApplication  =   process.getAttribute("JobApplication") != null ? (JobApplication) process.getAttribute("JobApplication") : (JobApplication)request.getAttribute("JobApplication");
        jobApplication                      =   jobApplication.getInTransaction(objTran);
        
        if(jobApplication.getStatus() != ObjectStatus.NEW)  //getInTransaction will return NULL for NEW object, resulting NPE
        {
            jobApplication  =   (JobApplication) jobApplication.getInTransaction (objTran);
            
            final Long  applicationID   =   jobApplication.getID().longID();
            
            objTran.runInNewTX((ObjectTransaction newTran) ->
            {
                updateJobApplication(newTran, applicationID);
            });
        }
        else
        {
            updateJobApplication(objTran, jobApplication.getID().longID());
        }
        
        process.setAttribute("JobApplication", jobApplication);
        
        return super.processForm(process, submission, params);
    }

    
    @Override
    public void validate(ORMProcessState process, SubmissionDetails submission, MultiException exceptions, Map params) throws StorageException 
    {
        HttpServletRequest  request         =   submission.getRequest();
        ObjectTransaction   objTran         =   ObjectTransaction.getTransaction();
        JobApplication      application     =   process.getAttribute("JobApplication") != null ? (JobApplication) process.getAttribute("JobApplication") : (JobApplication)request.getAttribute("JobApplication");
        JobApplication      jobApplication  =   application.getInTransaction(objTran);
        
        if(!jobApplication.cultureCompleted())
        {
            BusinessObjectParser.assertFieldCondition(jobApplication.getCandidate().getCultureCriteriaAnswersCount()>0, application, JobApplication.FIELD_ObjectID, "completeCulture", exceptions, true, request);
        }
        
        if(jobApplication.isIncludeAssessmentCriteria())
        {
            AssessmentCriteriaAnswer[]  criteria =   AssessmentCriteriaAnswer.SearchByAll().andJobApplication(new EqualsFilter<>(jobApplication)).search(objTran);

            BusinessObjectParser.assertFieldCondition(jobApplication.getJob().getAssessmentCriteriasCount() == criteria.length, application, JobApplication.FIELD_ObjectID, "completeAssessment", exceptions, true, request);
        }
        
        super.validate(process, submission, exceptions, params);
    }
    
    //This function was created to update Job Application in separate transaction otherwise it doesn't return submitted ANSWERS properly, and thus Test Analysis doesn't work.
    private void updateJobApplication(ObjectTransaction objTran, Long jobApplicationID) throws FieldException
    {
        JobApplication  jobApplication  =   JobApplication.getJobApplicationByID(objTran, jobApplicationID);
        
        LogMgr.log(JobApplication.LOG, LogLevel.PROCESSING2, "CompleteApplicationFP Job Application :", jobApplication);
        
        jobApplication.setApplicationStatus(ApplicationStatus.SUBMITTED);
        jobApplication.setSubmittedDate(new Date());
        
        AnalysisEngine.analyseAnswers(jobApplication.getCandidate(), jobApplication.getJob().getLevel(), jobApplication.getCompletedAnswers()); //getCompletedAnswers() returns collection now
        
        if(jobApplication.hasFailedEssentialRequirements())
        {
            jobApplication.setApplicationStatus(ApplicationStatus.UNSUITABLE);
        }
        
        LogMgr.log(JobApplication.LOG, LogLevel.PROCESSING2, "Job Application Completed", jobApplication);
    }
}