package performa.utils;

import java.util.*;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.rdbms.filters.GreaterThanEqualFilter;
import oneit.objstore.rdbms.filters.LessThanFilter;
import oneit.security.*;
import oneit.utils.Tuple;
import performa.orm.*;
import performa.orm.types.Importance;
import performa.orm.types.JobSortOption;
import oneit.objstore.utils.*;
import oneit.utils.*;
import oneit.utils.filter.CollectionFilter;
import oneit.utils.filter.Filter;
import performa.orm.types.AppSortOption;

/**
 *
 * @author Harsh
 */
public class Utils
{
    public static final String  ROLE_APPLICANT                  =   "TL_Applicant";
    public static final String  ROLE_CLIENT                     =   "TL_Client";
    public static final String  PRIV_ACCESS_ADMIN_PORTAL        =   "TL_AccessAdminPortal";
    public static final String  PRIV_ACCESS_APPLICANT_PORTAL    =   "TL_AccessApplicantPortal";
    public static final String  LEVEL_GENERAL_PURPOSE           =   "General Purpose";
    public static final String  LEVEL_SALES                     =   "Sales";
    public static final String  LEVEL_MANAGEMENT                =   "Management";
    public static final String  LEVEL_EXECUTIVE                 =   "Executive";
    
    public static Role  getRole(String role, ObjectTransaction transaction)
    {
        return Role.SearchByNAME().byName(role).search(transaction);
    }
    
    public static Privilege  getPrivilege(String priv, ObjectTransaction transaction)
    {
        return Privilege.searchNAME(transaction, priv);
    }
    
    public static boolean checkAdminPortalAccess(SecUser secUser)
    {
        return (secUser != null && secUser.hasPrivilege(PRIV_ACCESS_ADMIN_PORTAL));
    }
    
    public static boolean checkApplicantPortalAccess(SecUser secUser)
    {
        return (secUser != null && secUser.hasPrivilege(PRIV_ACCESS_APPLICANT_PORTAL));
    }
    
    public static Candidate getCandidateUser (ObjectTransaction objTran)
    {
        return  SecUser.getTXUser(objTran).getExtension(Candidate.REFERENCE_Candidate);
    }
    
    public static Importance[] getImportancesForAssessment()
    {
        List<Importance>    importances =   new ArrayList<>();
        
        for(Importance importance : Importance.getImportanceArray())
        {
            if(importance.getConsiderForAssessment())
            {
                importances.add(importance);
            }
        }
        return importances.toArray(new Importance[0]);
    }
    
    // TODO: Levels hardcoded for this phase, needs to be changed later!
    public static List<Tuple.T3> getLevelsForComprehensive(ObjectTransaction objTran)
    {
        List<Tuple.T3>  levels  =   new ArrayList();
        
        levels.add(new Tuple.T3(Level.searchName(objTran, LEVEL_GENERAL_PURPOSE), "General Purpose", "gn-pu"));
        levels.add(new Tuple.T3(Level.searchName(objTran, LEVEL_SALES), "Sales", "sales-pic"));
        levels.add(new Tuple.T3(Level.searchName(objTran, LEVEL_MANAGEMENT), "Management", "manag-pic"));
        levels.add(new Tuple.T3(Level.searchName(objTran, LEVEL_EXECUTIVE), "Executive", "exe-pic"));
        
        return levels;
    }
    
    
    //to sort jobs list
    public static List<Job> getJobsSorted(Job[] jobs, JobSortOption jobSortOption)
    {
        ObjectTransform transform   =   Job.pipesJob().toObjectCreated();
        Comparator      comparator  =   CollectionUtils.DEFAULT_COMPARATOR;
        
        if(jobSortOption==JobSortOption.OLDEST)
        {
            transform   =   Job.pipesJob().toOpenDate();
            comparator  =   CollectionUtils.DEFAULT_COMPARATOR;
        }
        else if(jobSortOption==JobSortOption.NEWEST)
        {
            transform   =   Job.pipesJob().toOpenDate();
            comparator  =   CollectionUtils.reverse(CollectionUtils.DEFAULT_COMPARATOR);
        }
        else if(jobSortOption==JobSortOption.CLOSING_SOON)
        {
            transform   =   Job.pipesJob().toApplyBy();
            comparator  =   CollectionUtils.DEFAULT_COMPARATOR_NULLS_FIRST;
        }
        else if(jobSortOption==JobSortOption.ALPHA_A_Z)
        {
            transform   =   Job.pipesJob().toJobTitle();
            comparator  =   CollectionUtils.CASE_INSENSITIVE_COMPARATOR;
        }
        else if(jobSortOption==JobSortOption.ALPHA_Z_A)
        {
            transform   =   Job.pipesJob().toJobTitle();
            comparator  =   CollectionUtils.reverse(CollectionUtils.CASE_INSENSITIVE_COMPARATOR);
        }
        
        return ObjstoreUtils.sort( Arrays.asList(jobs), 
                        new ObjectTransform[]{transform},
                        new Comparator[]{comparator});
    }
    
    
    public static int getClosingSoonJobCount(Job[] jobs)
    {
        Filter<Job> filter          =   Job.SearchByAll()
                                            .andApplyBy(new LessThanFilter<>(DateDiff.add(DateDiff.getToday(), Calendar.DATE, 5)))
                                            .andApplyBy(new GreaterThanEqualFilter<>(DateDiff.getToday()));
        
        Object[]    closingSoonJobs = CollectionFilter.filterArray(jobs, filter);
        
        return closingSoonJobs.length;
    }
    
    //to sort application list
    public static List<JobApplication> getApplicationsSorted(JobApplication[] applications, AppSortOption appSortOption)
    {
        ObjectTransform transform   =   JobApplication.pipesJobApplication().toObjectCreated();
        Comparator      comparator  =   CollectionUtils.DEFAULT_COMPARATOR;
        
        if(appSortOption==AppSortOption.OLDEST)
        {
            transform   =   JobApplication.pipesJobApplication().toSubmittedDate();
            comparator  =   CollectionUtils.DEFAULT_COMPARATOR;
        }
        else if(appSortOption==AppSortOption.NEWEST)
        {
            transform   =   JobApplication.pipesJobApplication().toSubmittedDate();
            comparator  =   CollectionUtils.reverse(CollectionUtils.DEFAULT_COMPARATOR);
        }
        else if(appSortOption==AppSortOption.RANK) 
        {
            transform   =   JobApplication.pipesJobApplication().toOverallSuitability();
            comparator  =   CollectionUtils.reverse(CollectionUtils.DEFAULT_COMPARATOR);
        }
        else if(appSortOption==AppSortOption.ALPHA_A_Z)
        {
            transform   =   JobApplication.pipesJobApplication().toCandidate().toUser().toFirstName();
            comparator  =   CollectionUtils.CASE_INSENSITIVE_COMPARATOR;
        }
        else if(appSortOption==AppSortOption.ALPHA_Z_A)
        {
            transform   =   JobApplication.pipesJobApplication().toCandidate().toUser().toFirstName();
            comparator  =   CollectionUtils.reverse(CollectionUtils.CASE_INSENSITIVE_COMPARATOR);
        }
        
        return ObjstoreUtils.sort( Arrays.asList(applications), 
                        new ObjectTransform[]{transform},
                        new Comparator[]{comparator});
    }
}
