package performa.batch;

import oneit.appservices.batch.ORMBatch;
import oneit.logging.*;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.StorageException;
import oneit.objstore.rdbms.filters.LessThanFilter;
import oneit.utils.DateDiff;
import oneit.utils.math.NullArith;
import oneit.utils.parsers.FieldException;
import performa.orm.HiringTeam;
import performa.orm.Job;
import performa.orm.types.JobStatus;


public class CloseJobBatch  extends ORMBatch
{
    public static LoggingArea CLOSE_JOB_BATCH = LoggingArea.createLoggingArea("CloseJobBatch");

    @Override
    public void run(ObjectTransaction ot) throws StorageException, FieldException
    {
        LogMgr.log (CLOSE_JOB_BATCH, LogLevel.PROCESSING1, "RUNNING Close Job Batch");

        Job[]   expiringJobs    = Job.SearchByAll()
                                        .andApplyBy(new LessThanFilter<>(DateDiff.getToday()))
                                        .search(ot);
        
        for (Job job : expiringJobs)
        {
            job.setJobStatus(JobStatus.COMPLETE);
            job.setIsManuallyClosed(Boolean.FALSE);
            
            LogMgr.log(CLOSE_JOB_BATCH, LogLevel.PROCESSING1, "Setting Job Status to Closed in job : ", job);
            
            if(job.getJobApplicationsCount() == 0)
            {
                HiringTeam  hiringTeam  =   job.getHiringTeam();
                HiringTeam  billingTeam =   hiringTeam == null || hiringTeam.getManageOwnBilling() ? hiringTeam : hiringTeam.getBilledByTeam();

                LogMgr.log(CLOSE_JOB_BATCH, LogLevel.PROCESSING1, "No Applicants for job: ", job,  " hence crediting account : ", billingTeam);
                
                if(billingTeam == null)
                {
                    continue;
                }
                
                if(billingTeam.isTrue(billingTeam.getOnTrial()))
                {
                    billingTeam.setTrialJobCount(billingTeam.getTrialJobCount() - 1);
                    LogMgr.log(CLOSE_JOB_BATCH, LogLevel.PROCESSING1, "Reducing trail job count of hiring team : ", billingTeam);
                }
                else
                {
                    if(billingTeam.getIsPPJ())
                    {
                        billingTeam.setPPJCredits(NullArith.add(billingTeam.getPPJCredits(), 1).intValue());
                        LogMgr.log(CLOSE_JOB_BATCH, LogLevel.PROCESSING1, "Increasing PPJ Credits of hiring team : ", billingTeam);
                    }
                    else
                    {
                        if(billingTeam.getUsedCredits() > billingTeam.getAvailableCredits())
                        {
                            billingTeam.setAvailableCredits(NullArith.add(billingTeam.getAvailableCredits(), 1).intValue());
                            LogMgr.log(CLOSE_JOB_BATCH, LogLevel.PROCESSING1, "Increasing Available Credits of hiring team (to recover usage records on stripe) : ", billingTeam);
                        }

                        billingTeam.setUsedCredits(NullArith.subtract(billingTeam.getUsedCredits(), 1).intValue());
                        LogMgr.log(CLOSE_JOB_BATCH, LogLevel.PROCESSING1, "Reducing used credits of hiring team ", billingTeam);
                    }
                }
            }
        }
    }
}