/*
 * 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.jackrabbit.oak.segment.file;

import static java.lang.Thread.currentThread;
import static java.util.concurrent.Executors.defaultThreadFactory;
import static java.util.concurrent.Executors.newScheduledThreadPool;
import static java.util.concurrent.TimeUnit.SECONDS;

import java.io.Closeable;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A simple scheduler for executing and scheduling tasks in the background.
 * This implementation delegates all background execution to an instance
 * of a {@link ScheduledExecutorService} with core pool size 1. The behaviour
 * of this underlying scheduler service determines the semantics of the methods
 * in this class. Namely: Execution of background tasks never overlaps and is
 * FIFO for tasks scheduled for the same time.
 * In addition all tasks scheduled through methods of this class are automatically
 * wrapped into {@link SafeRunnable} instances. The background thread executing
 * submitted tasks is a deamon thread.
 */
public class Scheduler implements Closeable {
    private static int schedulerNumber = 0;
    private static final Logger LOG = LoggerFactory.getLogger(Scheduler.class);

    @NotNull
    private final AtomicLong executionCounter = new AtomicLong();

    @NotNull
    private final String name;

    @NotNull
    private final ScheduledExecutorService executor;

    /**
     * Create a new instance with the given {@code name}. The name is used to
     * derive the default name of the background thread from..
     * @param name
     */
    public Scheduler(@Nullable String name) {
        if (name == null) {
            synchronized (Scheduler.class) {
                this.name = "scheduler-" + schedulerNumber;
                schedulerNumber++;
            }
        } else {
            this.name = name;
        }
        this.executor = newScheduledThreadPool(1, new SchedulerThreadFactory(this.name));
    }

    /**
     * Immediately execute {@code task}. The background thread's name is
     * set to {@code name} during execution of {@code task}.
     * @param name
     * @param task
     * @see ScheduledExecutorService#execute(Runnable)
     */
    public void execute(@NotNull String name, @NotNull Runnable task) {
        executor.execute(new SafeRunnable(name, task));
    }

    /**
     * Run {@code task} once after some delay. The background thread's name is
     * set to {@code name} during execution of {@code task}.
     * @param name
     * @param delay
     * @param unit
     * @param task
     * @see ScheduledExecutorService#schedule(Runnable, long, TimeUnit)
     */
    public void scheduleOnce(
            @NotNull String name,
            long delay,
            @NotNull TimeUnit unit,
            @NotNull Runnable task) {
        executor.schedule(new SafeRunnable(name, task), delay, unit);
    }

    /**
     * Run {@code task} regularly at a given interval. The background thread's name is
     * set to {@code name} during execution of {@code task}.
     * @param name
     * @param period
     * @param unit
     * @param task
     * @see ScheduledExecutorService#scheduleAtFixedRate(Runnable, long, long, TimeUnit)
     */
    public void scheduleAtFixedRate(
            @NotNull String name,
            long period,
            @NotNull TimeUnit unit,
            @NotNull Runnable task) {
        executor.scheduleAtFixedRate(new SafeRunnable(name, task), period, period, unit);
    }

    /**
     * Run {@code task} regularly after a fixed delay. The background thread's name is
     * set to {@code name} during execution of {@code task}.
     * @param name
     * @param delay
     * @param unit
     * @param task
     * @see ScheduledExecutorService#scheduleWithFixedDelay(Runnable, long, long, TimeUnit)
     */
    public void scheduleWithFixedDelay(
            @NotNull String name,
            long delay,
            @NotNull TimeUnit unit,
            @NotNull Runnable task) {
        executor.scheduleWithFixedDelay(new SafeRunnable(name, task), delay, delay, unit);
    }

    /**
     * Close this scheduler.
     * @see ScheduledExecutorService#shutdown()
     */
    @Override
    public void close() {
        try {
            executor.shutdown();
            if (executor.awaitTermination(60, SECONDS)) {
                LOG.debug("The scheduler {} was successfully shut down", name);
            } else {
                LOG.warn("The scheduler {} takes too long to shut down", name);
            }
        } catch (InterruptedException e) {
            LOG.warn("Interrupt while shutting down he scheduler {}", name, e);
            currentThread().interrupt();
        }
    }

    private static class SchedulerThreadFactory implements ThreadFactory {
        private final ThreadFactory threadFactory = defaultThreadFactory();

        @NotNull
        private final String name;

        public SchedulerThreadFactory(@NotNull String name) {
            this.name = name;
        }

        @Override
        public Thread newThread(@NotNull Runnable runnable) {
            Thread thread = threadFactory.newThread(runnable);
            thread.setName(name);
            thread.setDaemon(true);
            return thread;
        }
    }

}
