package performa.search;

import java.util.ArrayList;
import java.util.List;
import oneit.logging.LogLevel;
import oneit.logging.LogMgr;
import oneit.logging.LoggingArea;
import oneit.objstore.*;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.objstore.services.TransactionTask;
import oneit.utils.parsers.FieldException;
import performa.orm.*;
import performa.orm.types.*;


public class SearchApplicant extends BaseSearchApplicant
{
    private static final long serialVersionUID = 0L;
    public  static final LoggingArea    LOG =   LoggingArea.createLoggingArea("SearchApplicant");

    // This constructor should not be called
    public SearchApplicant ()
    {
        // Do not add any code to this, always put it in initialiseNewObject
    }
    
    @Override
    public BaseBusinessClass[] doSearch() 
    {
        final List<JobApplication> appResults = new ArrayList<>();

        try 
        {
            getTransaction().runInNewTX(new TransactionTask()
            {                              
                @Override
                public void run(ObjectTransaction newObjTran) throws FieldException, StorageException
                {
                    JobApplication[]    results   =   JobApplication.SearchByDetails()
                                                            .byName(getDetails())
                                                            .andJob(new EqualsFilter<>(getJob()))
                                                            .search(newObjTran); 
                    for(JobApplication app : results)
                    {
                        ApplicationStatus   appStatus   =   app.getApplicationStatus();
                        
                        app =   app.getInTransaction(getTransaction());
                        
                        app.setApplicationStatus(appStatus);
                        
                        Answer[]    answers =   Answer.SearchByAll().andCandidate(new EqualsFilter<>(app.getCandidate())).search(getTransaction());

                        for (Answer answer: answers)
                        {
                            app.getCandidate().addToProfileAssessmentAnswers(answer);
                        }

                        AssessmentCriteriaAnswer[]  requirements    =   AssessmentCriteriaAnswer.SearchByAll().andJobApplication(new EqualsFilter<>(app)).search(getTransaction());

                        for (AssessmentCriteriaAnswer requirement: requirements)
                        {
                            app.addToAssessmentCriteriaAnswers(requirement);
                        }

                        CultureCriteriaAnswer[] cultures =   CultureCriteriaAnswer.SearchByAll().andCandidate(new EqualsFilter<>(app.getCandidate())).search(getTransaction());

                        for (CultureCriteriaAnswer culture: cultures)
                        {
                            app.getCandidate().addToCultureCriteriaAnswers(culture);
                        }

                        getJob().addToJobApplications(app);
                        appResults.add(app);
                    }
                }
                
            }); 
        } 
        catch (FieldException | StorageException ex) 
        {
            LogMgr.log(LOG, LogLevel.PROCESSING2 , ex, "Error when searching job applications");

        }
        
        return appResults.toArray(new JobApplication[0]);
    }
}