/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sling.commons.scheduler.impl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.sling.commons.scheduler.Job;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.quartz.JobKey;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;

@RunWith(MockitoJUnitRunner.class)
public class QuartzSchedulerTest {

    private Map<String, SchedulerProxy> proxies;
    private BundleContext context;
    private QuartzScheduler quartzScheduler;

    @Mock
    private Bundle bundle;

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @SuppressWarnings("unchecked")
    @Before
    public void setUp() throws Exception {
        context = MockOsgi.newBundleContext();
        quartzScheduler = ActivatedQuartzSchedulerFactory.create(context, "testName");
        Field sField = QuartzScheduler.class.getDeclaredField("schedulers");
        sField.setAccessible(true);
        this.proxies = (Map<String, SchedulerProxy>) sField.get(quartzScheduler);
    }

    @Test
    public void testRunNow() {
        InternalScheduleOptions scheduleOptions = (InternalScheduleOptions) quartzScheduler.NOW();
        assertNotNull("Trigger cannot be null", scheduleOptions.trigger);
        assertNull("IllegalArgumentException must be null", scheduleOptions.argumentException);

        scheduleOptions = (InternalScheduleOptions) quartzScheduler.NOW(1, 1);
        assertEquals("Times argument must be higher than 1 or -1", scheduleOptions.argumentException.getMessage());

        scheduleOptions = (InternalScheduleOptions) quartzScheduler.NOW(-1, 0);
        assertEquals("Period argument must be higher than 0", scheduleOptions.argumentException.getMessage());

        scheduleOptions = (InternalScheduleOptions) quartzScheduler.NOW(-1, 2);
        assertNull(scheduleOptions.argumentException);
        assertNotNull(scheduleOptions.trigger);

        scheduleOptions = (InternalScheduleOptions) quartzScheduler.NOW(2, 2);
        assertNull(scheduleOptions.argumentException);
        assertNotNull(scheduleOptions.trigger);
    }

    @Test
    public void testAddJobWithIncorrectJobObject() throws SchedulerException {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Job object is neither an instance of " + Runnable.class.getName() + " nor " + Job.class.getName());
        quartzScheduler.addJob(1L, 1L, "testName", new Object(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
    }

    @Test
    public void testAddJobWithoutCronExpression() throws SchedulerException {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Expression can't be null");
        quartzScheduler.addJob(1L, 1L, "testName", new Thread(), new HashMap<String, Serializable>(), null, true);
    }

    @Test
    public void testAddJobWithInvalidCronExpression() throws SchedulerException {
        String invalidExpression = "invalidExpression";
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Expressionis invalid : " + invalidExpression);
        quartzScheduler.addJob(1L, 1L, "testName", new Thread(), new HashMap<String, Serializable>(), invalidExpression, true);
    }

    @Test
    public void testAddJob() throws SchedulerException {
        quartzScheduler.addJob(1L, 1L, "testName", new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("testName")));
        assertFalse(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("wrongName")));
    }

    @Test
    public void testAddJobTwice() throws SchedulerException {
        quartzScheduler.addJob(1L, 1L, "testName", new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("testName")));
        //Add very same job twice to check that there is no conflicts and previous
        quartzScheduler.addJob(1L, 1L, "testName", new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("testName")));
    }

    @Test
    public void testRemoveJob() throws SchedulerException {
        String jobName = "testName";
        quartzScheduler.addJob(1L, 1L, jobName, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(jobName)));
        quartzScheduler.removeJob(1L, jobName);
        assertFalse(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(jobName)));
    }

    @Test
    public void testAtDateTime() {
        InternalScheduleOptions options = (InternalScheduleOptions) quartzScheduler.AT(null, 2, 1);
        assertEquals("Date can't be null", options.argumentException.getMessage());

        options = (InternalScheduleOptions) quartzScheduler.AT(new Date(), 1, 1);
        assertEquals("Times argument must be higher than 1 or -1", options.argumentException.getMessage());

        options = (InternalScheduleOptions) quartzScheduler.AT(new Date(), 2, 0);
        assertEquals("Period argument must be higher than 0", options.argumentException.getMessage());

        options = (InternalScheduleOptions) quartzScheduler.AT(new Date(), 2, 1);
        assertNull("IllegalArgumentException must be null", options.argumentException);
        assertNotNull("Trigger cannot be null", options.trigger);

        options = (InternalScheduleOptions) quartzScheduler.AT(new Date(), -1, 1);
        assertNull("IllegalArgumentException must be null", options.argumentException);
        assertNotNull("Trigger cannot be null", options.trigger);
    }

    @Test
    public void testAtTime() {
        InternalScheduleOptions options = (InternalScheduleOptions) quartzScheduler.AT(null);
        assertNotNull(options.argumentException);
        assertEquals("Date can't be null", options.argumentException.getMessage());
        assertNull(options.trigger);

        options = (InternalScheduleOptions) quartzScheduler.AT(new Date());
        assertNotNull(options.trigger);
        assertNull(options.argumentException);
    }

    @Test
    public void testPeriodicWithIncorrectPeriod() throws SchedulerException {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("Period argument must be higher than 0");
        quartzScheduler.addPeriodicJob(3L, 3L, "anyName", new Thread(), null, 0L, true, true);
    }

    @Test
    public void testPeriodic() throws SchedulerException {
        String jobName = "anyName";
        String otherJobName = "anyOtherName";

        quartzScheduler.addPeriodicJob(4L, 4L, jobName, new Thread(), null, 2L, true, true);
        assertTrue("Job must exists", proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(jobName)));

        quartzScheduler.addPeriodicJob(5L, 5L, otherJobName, new Thread(), null, 2L, true, false);
        assertTrue("Job must exists", proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(otherJobName)));
    }

    @Test
    public void testSchedule() {
        assertTrue(quartzScheduler.schedule(2L, 2L, new Thread(), new InternalScheduleOptions(TriggerBuilder.newTrigger())));
        assertFalse(quartzScheduler.schedule(2L, 2L, new Thread(), new InternalScheduleOptions(new IllegalArgumentException())));
    }

    @Test
    public void testUnschedule() throws Exception {
        String jobName = "jobToUnschedule";
        quartzScheduler.addJob(6L, 6L, jobName, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        assertTrue(quartzScheduler.unschedule(6L, jobName));

        quartzScheduler.addJob(6L, 6L, jobName, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        assertFalse(quartzScheduler.unschedule(6L, null));
        assertFalse(quartzScheduler.unschedule(6L, "incorrectName"));

        setInternalSchedulerToNull();
        assertFalse(quartzScheduler.unschedule(6L, jobName));
        returnInternalSchedulerBack();
    }

    @Test
    public void testBundleChangedWithStoppedBundle() throws SchedulerException {
        String firstJob = "testName1";
        String secondJob = "testName2";
        when(bundle.getBundleId()).thenReturn(2L);

        quartzScheduler.addJob(1L, 1L, firstJob, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        quartzScheduler.addJob(2L, 2L, secondJob, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);

        BundleEvent event = new BundleEvent(BundleEvent.STOPPED, bundle);
        quartzScheduler.bundleChanged(event);

        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(firstJob)));
        assertFalse(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(secondJob)));
    }

    @Test
    public void testBundleChangedWithStartedBundle() throws SchedulerException {
        String firstJob = "testName1";
        String secondJob = "testName2";
        when(bundle.getBundleId()).thenReturn(2L);

        quartzScheduler.addJob(1L, 1L, firstJob, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        quartzScheduler.addJob(2L, 2L, secondJob, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);

        BundleEvent event = new BundleEvent(BundleEvent.STARTED, bundle);
        quartzScheduler.bundleChanged(event);

        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(firstJob)));
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(secondJob)));
    }

    @Test
    public void testBundleChangedWithoutScheduler() throws Exception {
        String firstJob = "testName1";
        String secondJob = "testName2";
        Long bundleIdToRemove = 2L;
        when(bundle.getBundleId()).thenReturn(bundleIdToRemove);

        quartzScheduler.addJob(1L, 1L, firstJob, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);
        quartzScheduler.addJob(bundleIdToRemove, 2L, secondJob, new Thread(), new HashMap<String, Serializable>(), "0 * * * * ?", true);

        setInternalSchedulerToNull();

        BundleEvent event = new BundleEvent(BundleEvent.STOPPED, bundle);
        quartzScheduler.bundleChanged(event);

        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(firstJob)));
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey(secondJob)));

        returnInternalSchedulerBack();
    }

    @Test
    public void testThreadPools() throws SchedulerException {
        final Date future = new Date(System.currentTimeMillis() + 1000 * 60 * 60);
        quartzScheduler.schedule(1L, 1L, new Thread(), quartzScheduler.AT(future).name("j1").threadPoolName("tp1"));
        quartzScheduler.schedule(1L, 2L, new Thread(), quartzScheduler.AT(future).name("j2").threadPoolName("tp2"));
        quartzScheduler.schedule(1L, 2L, new Thread(), quartzScheduler.AT(future).name("j3").threadPoolName("allowed"));

        assertNull(proxies.get("tp1"));
        assertNull(proxies.get("tp2"));
        assertNotNull(proxies.get("allowed"));

        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j1")));
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j2")));
        assertTrue(proxies.get("allowed").getScheduler().checkExists(JobKey.jobKey("j3")));
    }

    @Test
    public void testNameAcrossPools() throws SchedulerException {
        final Date future = new Date(System.currentTimeMillis() + 1000 * 60 * 60);
        quartzScheduler.schedule(1L, 1L, new Thread(), quartzScheduler.AT(future).name("j1").threadPoolName("tp1"));
        assertNull(proxies.get("tp1"));
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j1")));
        quartzScheduler.unschedule(1L, "j1");
        assertFalse(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j1")));

        quartzScheduler.schedule(1L, 1L, new Thread(), quartzScheduler.AT(future).name("j1").threadPoolName("allowed"));
        assertFalse(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j1")));
        assertTrue(proxies.get("allowed").getScheduler().checkExists(JobKey.jobKey("j1")));
        quartzScheduler.unschedule(1L, "j1");
        assertFalse(proxies.get("allowed").getScheduler().checkExists(JobKey.jobKey("j1")));

        quartzScheduler.schedule(1L, 1L, new Thread(), quartzScheduler.AT(future).name("j1"));
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j1")));
        assertFalse(proxies.get("allowed").getScheduler().checkExists(JobKey.jobKey("j1")));
        quartzScheduler.unschedule(1L, "j1");
        assertFalse(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j1")));

        quartzScheduler.schedule(1L, 1L, new Thread(), quartzScheduler.AT(future).name("j1").threadPoolName("tp1"));
        assertNull(proxies.get("tp1"));
        assertTrue(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j1")));
        quartzScheduler.unschedule(1L, "j1");
        assertFalse(proxies.get("testName").getScheduler().checkExists(JobKey.jobKey("j1")));
    }

    @After
    public void deactivateScheduler() throws NoSuchFieldException, IllegalAccessException {
        if (quartzScheduler.getSchedulers().isEmpty()) {
            returnInternalSchedulerBack();
        }
        quartzScheduler.deactivate(context);
    }

    private void setInternalSchedulerToNull() throws NoSuchFieldException, IllegalAccessException {
        Field sField = QuartzScheduler.class.getDeclaredField("schedulers");
        sField.setAccessible(true);
        sField.set(quartzScheduler, new HashMap<String, SchedulerProxy>());
    }

    private void returnInternalSchedulerBack() throws NoSuchFieldException, IllegalAccessException {
        Field sField = QuartzScheduler.class.getDeclaredField("schedulers");
        sField.setAccessible(true);
        if (quartzScheduler.getSchedulers().isEmpty() && this.proxies != null) {
            sField.set(quartzScheduler, this.proxies);
        }
    }
}
