/*
 * 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.tuscany.sca.core.work.impl;

import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadFactory;

import org.apache.tuscany.sca.work.WorkSchedulerException;

/**
 * A thread-pool based implementation for the JSR-237 work manager.
 * <p/>
 * <p/>
 * This implementation supports only local work.
 * <p/>
 * TODO Elaborate the implementation. </p>
 *
 * @version $Rev$ $Date$
 */
public class ThreadPoolWorkManager {

    // Map of work items currently handled by the work manager
    private Map<WorkItem, WorkListener> workItems = new ConcurrentHashMap<WorkItem, WorkListener>();

    // Thread-pool
    protected ExecutorService executor;

    /**
     * Initializes the thread-pool.
     *
     * @param threadPoolSize Thread-pool size. If the size <1, then a cached pool is created
     */
    public ThreadPoolWorkManager(int threadPoolSize) {
        ThreadFactory factory = new ThreadFactory() {
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setDaemon(true);
                return thread;
            }
        };
        if (threadPoolSize <= 0) {

            // Creates a new Executor, use a custom ThreadFactory that
            // creates daemon threads.
            executor = Executors.newCachedThreadPool(factory);
        } else {
            executor = Executors.newFixedThreadPool(threadPoolSize, factory);
        }
    }

    /**
     * Schedules a unit of work asynchronously.
     *
     * @param work Work that needs to be scheduled.
     * @return Work Work item representing the asynchronous work
     */
    public WorkItem schedule(Work work) throws IllegalArgumentException {
        return schedule(work, null);
    }

    /**
     * Schedules a unit of work asynchronously.
     *
     * @param work         Work that needs to be scheduled.
     * @param workListener Work listener for callbacks.
     * @return Work Work item representing the asynchronous work
     */
    public WorkItem schedule(Work work, WorkListener workListener) throws IllegalArgumentException {

        WorkItem workItem = new WorkItem(UUID.randomUUID().toString(), work);
        if (workListener != null) {
            workItems.put(workItem, workListener);
        }
        workAccepted(workItem, work);
        if (scheduleWork(work, workItem)) {
            return workItem;
        } else {
            workItem.setStatus(WorkEvent.WORK_REJECTED);
            if (workListener != null) {
                workListener.workRejected(new WorkEvent(workItem));
            }
            throw new IllegalArgumentException("Unable to schedule work");
        }
    }

    /**
     * Wait for all the specified units of work to finish.
     *
     * @param works   Units of the work that need to finish.
     * @param timeout Timeout for waiting for the units of work to finish.
     */
    public boolean waitForAll(Collection works, long timeout) {
        throw new UnsupportedOperationException("waitForAll not supported");
    }

    /**
     * Wait for any of the specified units of work to finish.
     *
     * @param works   Units of the work that need to finish.
     * @param timeout Timeout for waiting for the units of work to finish.
     */
    public Collection waitForAny(Collection works, long timeout) {
        throw new UnsupportedOperationException("waitForAny not supported");
    }

    /**
     * Method provided for subclasses to indicate a work acceptance.
     *
     * @param workItem Work item representing the work that was accepted.
     * @param work     Work that was accepted.
     */
    private void workAccepted(final WorkItem workItem, final Work work) {
        WorkListener listener = workItems.get(workItem);
        if (listener != null) {
            workItem.setStatus(WorkEvent.WORK_ACCEPTED);
            WorkEvent event = new WorkEvent(workItem);
            listener.workAccepted(event);
        }
    }

    /*
     * Method to indicate a work start.
     */
    private void workStarted(final WorkItem workItem, final Work work) {
        WorkListener listener = workItems.get(workItem);
        if (listener != null) {
            workItem.setStatus(WorkEvent.WORK_STARTED);
            WorkEvent event = new WorkEvent(workItem);
            listener.workStarted(event);
        }
    }

    /*
     * Method to indicate a work completion.
     */
    private void workCompleted(final WorkItem workItem, final Work work) {
        workCompleted(workItem, work, null);
    }

    /*
     * Method to indicate a work completion.
     */
    private void workCompleted(final WorkItem workItem, final Work work, final WorkSchedulerException exception) {
        WorkListener listener = workItems.get(workItem);
        if (listener != null) {
            workItem.setStatus(WorkEvent.WORK_COMPLETED);
            workItem.setResult(work);
            workItem.setException(exception);
            WorkEvent event = new WorkEvent(workItem);
            listener.workCompleted(event);
            workItems.remove(workItem);
        }
    }

    /*
     * Schedules the work using the ThreadPool.
     */
    private boolean scheduleWork(final Work work, final WorkItem workItem) {
        try {
            executor.execute(new DecoratingWork(workItem, work));
            return true;
        } catch (RejectedExecutionException ex) {
            return false;
        }
    }

    /*
     * Class that decorates the original worker so that it can get callbacks when work is done.
     */
    private final class DecoratingWork implements Runnable {

        // Work item for this work.
        private WorkItem workItem;

        // The original work.
        private Work decoratedWork;

        /*
         * Initializes the work item and underlying work.
         */
        private DecoratingWork(final WorkItem workItem, final Work decoratedWork) {
            this.workItem = workItem;
            this.decoratedWork = decoratedWork;
        }

        /*
         * Overrides the run method.
         */
        public void run() {
            workStarted(workItem, decoratedWork);
            try {
                decoratedWork.run();
                workCompleted(workItem, decoratedWork);
            } catch (Throwable th) {
                workCompleted(workItem, decoratedWork, new WorkSchedulerException(th.getMessage(), th));
            }
        }

    }

    public void destroy() {
        executor.shutdown();
    }

    public ExecutorService getExecutorService() {
        return executor;
    }

}

