package com.capgemini.reports.common.scheduling;

import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.reports.exceptions.InvalidInputException;
import com.capgemini.reports.exceptions.NotSupportedException;
import com.capgemini.reports.execution.AbstractExecutionReport;
import com.capgemini.reports.quartz.TriggerPreparator;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
import org.quartz.CronTrigger;
import org.quartz.JobKey;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.springframework.mock.web.MockHttpServletRequest;


@Slf4j
public class SchedulingServletTest {

    private final String LAUNCH_DATE_STR = SettingsHelper.getDelayedLaunchHour();

    /**
     * JUnit test.
     * 
     * @throws NotSupportedException Should not happen
     */
    @Test
    public void testGetExecutionReportImpl() throws NotSupportedException {
        // Get a mock HttpRequest to test the methods of the servlet
        MockHttpServletRequest mockRequest = getMockHttpServletRequest();

        SubmitServletScheduling servlet = new SubmitServletScheduling();
        AbstractExecutionReport<?, ?> reportTest = servlet.getExecutionReportImpl(mockRequest);

        // Check
        Assert.assertNotNull(reportTest);
        log.info(reportTest.toString());
    }

    /**
     * JUnit test.
     * 
     * @throws InvalidInputException Should not happen
     */
    @Test
    public void testGetSchedulingTrigger() throws InvalidInputException {
        // Initialize the variables
        Long uid = (long) 123456789;
        int priority = 1;

        // Separate hours and minutes (format hour:minute)
        String[] tableStrLaunchTime = LAUNCH_DATE_STR.split(":");
        int launchHour = Integer.parseInt(tableStrLaunchTime[0]);
        int launchMinute = Integer.parseInt(tableStrLaunchTime[1]);

        // Get a mock HttpRequest to test the methods of the servlet
        MockHttpServletRequest mockRequest = getMockHttpServletRequest();
        String schedulingName = mockRequest.getParameter("scheduling_name");

        SubmitServletScheduling servlet = new SubmitServletScheduling();

        Trigger triggerTest = TriggerPreparator.prepareScheduledTrigger(uid, priority, schedulingName, servlet.getSchedulingData(mockRequest));

        // Check
        Assert.assertNotNull(triggerTest);
        CronTrigger cronTrigger = (CronTrigger) triggerTest;
        log.info(cronTrigger.toString());
        JobKey jobKey = cronTrigger.getJobKey();
        TriggerKey triggerKey = cronTrigger.getKey();
        Assert.assertEquals("the name of the job is not the same as the expected value", "job_name_" + uid, jobKey.getName());
        Assert.assertEquals("the group of the job is not the same as the expected value", "scheduled", jobKey.getGroup());
        Assert.assertEquals("the name of the trigger is not the same as the expected value", "trigger_name_" + uid, triggerKey.getName());
        Assert.assertEquals("the group of the trigger is not the same as the expected value", "scheduled", triggerKey.getGroup());
        String schedulName = mockRequest.getParameter("scheduling_name");
        Assert.assertEquals("the name of the planification is not the same as the expected value", schedulName, cronTrigger.getDescription());
        Assert.assertEquals("the cron express which manage the planification is not the same as the expected value", "0 " + launchMinute + " " + launchHour + " ? * *", cronTrigger.getCronExpression());
    }

    private MockHttpServletRequest getMockHttpServletRequest() {
        MockHttpServletRequest mockRequest = new MockHttpServletRequest();
        mockRequest.setParameter("report_code", "RTest");
        mockRequest.setParameter("scheduling_name", "myPlanif");
        mockRequest.setParameter("period", "daily");
        return mockRequest;
    }
}
