/*
 * Licensed under MIT (https://github.com/ligoj/ligoj/blob/master/LICENSE)
 */
package org.ligoj.bootstrap.core.curl;

import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.IntStream;

import javax.cache.annotation.CacheKey;
import javax.cache.annotation.CacheResult;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * A a cache manager for token used by the {@link CurlProcessor}
 */
@Component
public class CurlCacheToken {

	@Autowired
	protected ApplicationContext applicationContext;

	@Autowired
	private CurlCacheToken self = this;

	/**
	 * Return a cache token.
	 *
	 * @param key
	 *            The cache key.
	 * @param function
	 *            The {@link Function} used to retrieve the token value when the cache fails.
	 * @param retries
	 *            The amount of retries until the provider returns a not <code>null</code> value.
	 * @param exceptionSupplier
	 *            The exception used when the token cannot be retrieved.
	 * @return The token value either from the cache, either from the fresh computed one.
	 * @deprecated Use {@link #getTokenCache(String, UnaryOperator, int, Supplier)}
	 */
	@CacheResult(cacheName = "curl-tokens")
	@Deprecated
	public String getTokenCache(@CacheKey @NotNull final String key, final Function<String, String> function,
			final int retries, final Supplier<? extends RuntimeException> exceptionSupplier) {
		// First access to this function
		return getTokenCache(key, function::apply, retries, exceptionSupplier);
	}

	/**
	 * Return a cache token.
	 *
	 * @param key
	 *            The cache key.
	 * @param function
	 *            The {@link Function} used to retrieve the token value when the cache fails.
	 * @param retries
	 *            The amount of retries until the provider returns a not <code>null</code> value.
	 * @param exceptionSupplier
	 *            The exception used when the token cannot be retrieved.
	 * @return The token value either from the cache, either from the fresh computed one.
	 */
	@CacheResult(cacheName = "curl-tokens")
	public String getTokenCache(@CacheKey @NotNull final String key, final UnaryOperator<String> function,
			final int retries, final Supplier<? extends RuntimeException> exceptionSupplier) {
		// First access to this function
		return IntStream.range(0, retries).mapToObj(i -> function.apply(key)).filter(Objects::nonNull).findFirst()
				.orElseThrow(exceptionSupplier);
	}

	/**
	 * Return a synchronized cache token.
	 *
	 * @param synchronizeObject
	 *            The object used to synchronize the access to the cache.
	 * @param key
	 *            The cache key.
	 * @param function
	 *            The {@link Function} used to retrieve the token value when the cache fails.
	 * @param retries
	 *            The amount of retries until the provider returns a not <code>null</code> value.
	 * @param exceptionSupplier
	 *            The exception used when the token cannot be retrieved.
	 * @return The token value either from the cache, either from the fresh computed one.
	 * @deprecated Use {@link #getTokenCache(String, UnaryOperator, int, Supplier)}
	 */
	@Deprecated
	public String getTokenCache(@NotNull final Object synchronizeObject, @NotNull final String key,
			final Function<String, String> function, final int retries,
			final Supplier<? extends RuntimeException> exceptionSupplier) {
		return getTokenCache(synchronizeObject, key, function::apply, retries, exceptionSupplier);
	}

	/**
	 * Return a synchronized cache token.
	 *
	 * @param synchronizeObject
	 *            The object used to synchronize the access to the cache.
	 * @param key
	 *            The cache key.
	 * @param function
	 *            The {@link Function} used to retrieve the token value when the cache fails.
	 * @param retries
	 *            The amount of retries until the provider returns a not <code>null</code> value.
	 * @param exceptionSupplier
	 *            The exception used when the token cannot be retrieved.
	 * @return The token value either from the cache, either from the fresh computed one.
	 */
	public String getTokenCache(@NotNull final Object synchronizeObject, @NotNull final String key,
			final UnaryOperator<String> function, final int retries,
			final Supplier<? extends RuntimeException> exceptionSupplier) {
		synchronized (synchronizeObject) {
			// Use the jcache API to get the token
			return self.getTokenCache(key, function, retries, exceptionSupplier);
		}
	}

}

@@ -1313,2366 +1313,402 @@
 %0A%09 *
- @deprecated Use %7B@link #getTokenCache(String, UnaryOperator, int, Supplier)%7D%0A%09 */%0A%09@CacheResult(cacheName = %22curl-tokens%22)%0A%09@Deprecated%0A%09public String getTokenCache(@CacheKey @NotNull final String key, final Function%3CString, String%3E function,%0A%09%09%09final int retries, final Supplier%3C? extends RuntimeException%3E exceptionSupplier) %7B%0A%09%09// First access to this function%0A%09%09return getTokenCache(key, function::apply, retries, exceptionSupplier);%0A%09%7D%0A%0A%09/**%0A%09 * Return a cache token.%0A%09 *%0A%09 * @param key%0A%09 *            The cache key.%0A%09 * @param function%0A%09 *            The %7B@link Function%7D used to retrieve the token value when the cache fails.%0A%09 * @param retries%0A%09 *            The amount of retries until the provider returns a not %3Ccode%3Enull%3C/code%3E value.%0A%09 * @param exceptionSupplier%0A%09 *            The exception used when the token cannot be retrieved.%0A%09 * @return The token value either from the cache, either from the fresh computed one.%0A%09 */%0A%09@CacheResult(cacheName = %22curl-tokens%22)%0A%09public String getTokenCache(@CacheKey @NotNull final String key, final UnaryOperator%3CString%3E function,%0A%09%09%09final int retries, final Supplier%3C? extends RuntimeException%3E exceptionSupplier) %7B%0A%09%09// First access to this function%0A%09%09return IntStream.range(0, retries).mapToObj(i -%3E function.apply(key)).filter(Objects::nonNull).findFirst()%0A%09%09%09%09.orElseThrow(exceptionSupplier);%0A%09%7D%0A%0A%09/**%0A%09 * Return a synchronized cache token.%0A%09 *%0A%09 * @param synchronizeObject%0A%09 *            The object used to synchronize the access to the cache.%0A%09 * @param key%0A%09 *            The cache key.%0A%09 * @param function%0A%09 *            The %7B@link Function%7D used to retrieve the token value when the cache fails.%0A%09 * @param retries%0A%09 *            The amount of retries until the provider returns a not %3Ccode%3Enull%3C/code%3E value.%0A%09 * @param exceptionSupplier%0A%09 *            The exception used when the token cannot be retrieved.%0A%09 * @return The token value either from the cache, either from the fresh computed one.%0A%09 * @deprecated Use %7B@link #getTokenCache(String, UnaryOperator, int, Supplier)%7D%0A%09 */%0A%09@Deprecated%0A%09public String getTokenCache(@NotNull final Object synchronizeObject, @NotNull final String key,%0A%09%09%09final Function%3CString, String%3E function, final int retries,%0A%09%09%09final Supplier%3C? extends RuntimeException%3E exceptionSupplier) %7B%0A%09%09return getTokenCache(synchronizeObject, key, function::apply, retries, 
+/%0A%09@CacheResult(cacheName = %22curl-tokens%22)%0A%09public String getTokenCache(@CacheKey @NotNull final String key, final UnaryOperator%3CString%3E function,%0A%09%09%09final int retries, final Supplier%3C? extends RuntimeException%3E exceptionSupplier) %7B%0A%09%09// First access to this function%0A%09%09return IntStream.range(0, retries).mapToObj(i -%3E function.apply(key)).filter(Objects::nonNull).findFirst()%0A%09%09%09%09.orElseThrow(
 exce

Remove deprecated CURL functions