/* © SRSoftware 2025 */
package de.srsoftware.umbrella.user.model;

import static java.time.temporal.ChronoUnit.SECONDS;
import static java.util.Optional.empty;

import de.srsoftware.tools.Mappable;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class Lock implements Mappable {
	private static final Map<String, Lock> locks = new HashMap<>();

	private int	attempts;
	private LocalDateTime releaseTime;

	public Lock() {
		this.attempts = 0;
	}


	public int attempts() {
		return attempts;
	}

	public Lock count() {
		attempts++;
		if (attempts > 13) attempts = 13;
		var seconds = 5;
		for (long i = 0; i < attempts; i++) seconds *= 2;
		releaseTime = LocalDateTime.now().plusSeconds(seconds).truncatedTo(SECONDS);
		return this;
	}

	public static Optional<Lock> get(String key) {
		var failedLogin = locks.get(key);
		if (failedLogin == null || failedLogin.releaseTime().isBefore(LocalDateTime.now())) return empty();
		return Optional.of(failedLogin);
	}

	public static Lock lock(String key) {
		return locks.computeIfAbsent(key, k -> new Lock()).count();
	}


	public LocalDateTime releaseTime() {
		return releaseTime;
	}

	@Override
	public Map<String, Object> toMap() {
		return Map.of("attempts",attempts,"release_time",releaseTime);
	}

	public static void unlock(String key) {
		locks.remove(key);
	}
}
