package ru.yandex.webmaster3.storage.nca;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ru.yandex.webmaster3.core.util.W3Collectors;

/**
 * @author kravchenko99
 * @date 3/23/22
 */

@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class NcaRulesService {
    private static final int CACHE_EXPIRATION_DURATION = 10; // minutes

    private final NcaRulesYDao ncaRulesYDao;
    private static final Object KEY = new Object();


    private final LoadingCache<Object, Map<String, DateTime>> ncaCertificatesCache =
            CacheBuilder.newBuilder()
                    .refreshAfterWrite(CACHE_EXPIRATION_DURATION, TimeUnit.MINUTES)
                    .build(new CacheLoader<>() {
                        @Override
                        public Map<String, DateTime> load(Object key) {
                            return ncaRulesYDao.getAll();
                        }
                    });

    static boolean checkRuleForDomain(String domain, String rule) {
        return rule.equals(domain) || rule.equals("*." + domain) ||
                domain.matches(".+\\." + rule.replace("*.", "") + "$");
    }

    @NotNull
    public static String reverseDomain(String domain) {
        return String.join(".", Lists.reverse(List.of(domain.split("\\."))));
    }

    public Map<String, DateTime> getRulesForDomain(String domain) {
        Map<String, DateTime> ncaRules = ncaCertificatesCache.getUnchecked(KEY);

        return ncaRules.entrySet().stream().filter(x -> checkRuleForDomain(domain, x.getKey()))
                .collect(W3Collectors.toHashMap());

    }
}
