/*
 * Copyright (C) 2023, SAP SE and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.internal.util;

import java.text.MessageFormat;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.jgit.internal.JGitText;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A hook registered as a JVM shutdown hook managing a set of objects needing
 * cleanup during JVM shutdown. See {@link Runtime#addShutdownHook}.
 */
@SuppressWarnings("ImmutableEnumChecker")
public enum ShutdownHook {
	/**
	 * Singleton
	 */
	INSTANCE;

	/**
	 * Object that needs to cleanup on JVM shutdown.
	 */
	public interface Listener {
		/**
		 * Cleanup resources when JVM shuts down, called from JVM shutdown hook.
		 * <p>
		 * Implementations should be coded defensively
		 * <ul>
		 * <li>they should finish their work quickly
		 * <li>they should be written to be thread-safe and to avoid deadlocks
		 * insofar as possible
		 * <li>they should not rely blindly upon services that may have
		 * registered their own shutdown hooks and therefore may themselves be
		 * in the process of shutting down
		 * <li>attempts to use other thread-based services may lead to
		 * deadlocks.
		 * </ul>
		 * See {@link Runtime#addShutdownHook} for more details.
		 */
		public void onShutdown();
	}

	private static final Logger LOG = LoggerFactory
			.getLogger(ShutdownHook.class);

	private final Set<Listener> listeners = ConcurrentHashMap.newKeySet();

	private volatile boolean shutdownInProgress;

	private ShutdownHook() {
		try {
			Runtime.getRuntime().addShutdownHook(new Thread(this::cleanup));
		} catch (IllegalStateException e) {
			// ignore - the VM is already shutting down
		}
	}

	private void cleanup() {
		shutdownInProgress = true;
		ExecutorService runner = Executors.newWorkStealingPool();
		try {
			runner.submit(() -> {
				this.doCleanup();
				return null;
			}).get(30L, TimeUnit.SECONDS);
		} catch (RejectedExecutionException | InterruptedException
				| ExecutionException | TimeoutException e) {
			// message isn't localized since during shutdown there's no
			// guarantee which classes are still loaded
			LOG.error("Cleanup during JVM shutdown failed", e); //$NON-NLS-1$
		}
		runner.shutdownNow();
	}

	private void doCleanup() {
		listeners.parallelStream().forEach(this::notify);
	}

	private void notify(Listener l) {
		LOG.debug(JGitText.get().shutdownCleanup, l);
		try {
			l.onShutdown();
		} catch (RuntimeException e) {
			LOG.error(MessageFormat.format(
					JGitText.get().shutdownCleanupListenerFailed, l), e);
		}
	}

	/**
	 * Register object that needs cleanup during JVM shutdown if it is not
	 * already registered. Registration is disabled when JVM shutdown is already
	 * in progress.
	 *
	 * @param l
	 *            the object to call {@link Listener#onShutdown} on when JVM
	 *            shuts down
	 * @return {@code true} if this object has been registered
	 */
	public boolean register(Listener l) {
		if (shutdownInProgress) {
			return listeners.contains(l);
		}
		LOG.debug("register {} with shutdown hook", l); //$NON-NLS-1$
		listeners.add(l);
		return true;
	}

	/**
	 * Unregister object that no longer needs cleanup during JVM shutdown if it
	 * is still registered. Unregistration is disabled when JVM shutdown is
	 * already in progress.
	 *
	 * @param l
	 *            the object registered to be notified for cleanup when the JVM
	 *            shuts down
	 * @return {@code true} if this object is no longer registered
	 */
	public boolean unregister(Listener l) {
		if (shutdownInProgress) {
			return !listeners.contains(l);
		}
		LOG.debug("unregister {} from shutdown hook", l); //$NON-NLS-1$
		listeners.remove(l);
		return true;
	}

	/**
	 * Whether a JVM shutdown is in progress
	 *
	 * @return {@code true} if a JVM shutdown is in progress
	 */
	public boolean isShutdownInProgress() {
		return shutdownInProgress;
	}
}
