/*
 * 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.ace.scheduler;

import org.osgi.service.cm.ConfigurationException;

/**
 * Wrapper class for collecting a <code>Runnable</code> and its corresponding <code>recipe</code>(s).
 * Will schedule the task when both a schedule and a <code>Runnable</code> are available.<br>
 */
public class SchedulerTask {
    private final String m_name;
    private Runnable m_task;
    private String m_description;
    private Object m_configurationRecipe;
    private Object m_taskRecipe;
    private boolean m_recipeOverride;
    private Object m_currentRecipe;
    private Executer m_executer;

    /**
     * Creates instance of this class.
     * @param name The name of the runnable task.
     */
    SchedulerTask(String name) {
        if (name == null) {
            throw new IllegalArgumentException("A SchedulerTask's name cannot be null.");
        }
        m_name = name;
    }

    public String getName() {
        return m_name;
    }

    public String getDescription() {
        return m_description;
    }

    public Runnable getTask() {
        return m_task;
    }

    /**
     * Returns the currently most suited recipe, if any. This function not returning
     * <code>null</code> does not mean that the task is scheduled (it may still be missing
     * a <code>Runnable</code>).
     */
    public Object getCurrentRecipe() {
        return m_currentRecipe;
    }

    /**
     * Indicates whether this task is actually scheduled, and thus will run at some time
     * in the future, unless the schedule is set to <code>null</code>, or the <code>Runnable</code>
     * is removed.
     */
    public boolean isScheduled() {
        return m_executer != null;
    }

    /**
     * States a new set of properties for this task.
     * @param task A runnable to run for this task.
     * @param description A description of the task.
     * @param taskRecipe Optionally, a recipe for running this task.
     * @param recipeOverride Indicates whether or not the <code>recipe</code> passed in prevails over
     * any recipe provided by the <code>Scheduler</code>'s configuration.
     * @throws ConfigurationException When <code>recipe</code> is not <code>null</code>, and cannot
     * be decoded into a recipe.
     */
    public void updateTask(Runnable task, String description, Object taskRecipe, boolean recipeOverride) throws ConfigurationException {
        checkRecipe(taskRecipe);
        m_task = task;
        m_description = description;
        m_taskRecipe = taskRecipe;
        m_recipeOverride = recipeOverride;
    }

    /**
     * States a new recipe as coming from a configuration.
     * @param recipe Optionally, a recipe for running this task.
     * @throws ConfigurationException When <code>recipe</code> is not <code>null</code>, and cannot
     * be decoded into a recipe.
     */
    public void updateConfigurationRecipe(Object recipe) throws ConfigurationException {
        checkRecipe(recipe);
        m_configurationRecipe = recipe;
    }

    public void stop() {
        if (m_executer != null) {
            m_executer.stop();
            m_executer = null;
        }
    }

    public boolean process() {
        Object recipe = findRecipe();
        if ((recipe != null) && (m_task != null)) {
            if (!recipe.equals(m_currentRecipe) && (m_executer != null)) {
                m_executer.stop();
                m_executer = null;
            }
            if (m_executer == null) {
                m_executer = new Executer(m_task);
                m_executer.start(parseScheduleRecipe(recipe));
            }
        }
        else {
            // there is nothing to do, since there is no recipe or task
            stop();
        }
        m_currentRecipe = recipe;
        return ((recipe != null) || (m_task != null));
    }

    /**
     * Finds the most suitable recipe for the given task, using both the properties published
     * with the task, and the scheduler service's properties.
     * @return An <code>Object</code> representing the scheduler recipe, if any. If no suitable recipe can be found,
     * <code>null</code> will be returned.
     */
    private Object findRecipe() {
        if (m_recipeOverride) {
            if (m_taskRecipe != null) {
                return m_taskRecipe;
            }
            else if (m_configurationRecipe != null) {
                return m_configurationRecipe;
            }
        }
        else {
            if (m_configurationRecipe != null) {
                return m_configurationRecipe;
            }
            else if (m_taskRecipe != null) {
                return m_taskRecipe;
            }
        }
        return null;
    }

    /**
     * Decodes an Object into a schedule.
     * @param recipe An object representing a recipe.
     * @return A decoded representation of the recipe.
     */
    private long parseScheduleRecipe(Object recipe) {
        // For now assume just the number of milliseconds is in the string, we may want to do a
        // more 'cron-like' scheduling in the future
        return Long.valueOf(recipe.toString()).longValue();
    }

    /**
     * Helper method that checks whether a recipe is valid.
     * @throws ConfigurationException When <code>recipe</code> is not <code>null</code>, and cannot
     * be decoded into a recipe.
     */
    private void checkRecipe(Object recipe) throws ConfigurationException {
        if (recipe != null) {
            try {
                parseScheduleRecipe(recipe);
            }
            catch (NumberFormatException nfe) {
                throw new ConfigurationException(m_name, "Could not parse scheduling recipe for task", nfe);
            }
        }
    }
}