package ru.yandex.webmaster3.storage.verification;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.user.UserVerifiedHost;

import java.util.Comparator;
import java.util.function.Predicate;

/**
 * @author avhaliullin
 */
class VerificationInheritanceUtil {
    private static final Logger log = LoggerFactory.getLogger(VerificationInheritanceUtil.class);

    static Predicate<UserVerifiedHost> inheritableHostnamePredicate(WebmasterHostId hostId) {
        String normalizedNewHost = normalizeHost(hostId);
        log.info("inheritableHostnamePredicate created: {}, {}", hostId, normalizedNewHost);
        return userVerifiedHost -> {
            String normalizedTestHost = normalizeHost(userVerifiedHost.getWebmasterHostId());
            boolean res = normalizedNewHost.equals(normalizedTestHost) ||
                    normalizedNewHost.endsWith("." + normalizedTestHost);
            log.info("inheritableHostnamePredicate test: {}, {}, {}", userVerifiedHost.getWebmasterHostId(), normalizedTestHost, res);
            return res;
        };
    }

    static Comparator<UserVerifiedHost> inheritableHostsComparator(WebmasterHostId hostId) {
        boolean newHostIsWww = hostId.getPunycodeHostname().startsWith("www.");
        return (o1, o2) -> {
            int o1Depth = StringUtils.countMatches(normalizeHost(o1.getWebmasterHostId()), '.');
            int o2Depth = StringUtils.countMatches(normalizeHost(o2.getWebmasterHostId()), '.');
            // Глубина меньше - подходит хуже
            if (o1Depth < o2Depth) {
                // Говорим, что o1 "больше", тогда o2 сдвинется левее, как более подходящий
                return 1;
            } else if (o1Depth > o2Depth) {
                return -1;
            }

            boolean o1Www = o1.getWebmasterHostId().getPunycodeHostname().startsWith("www.");
            boolean o2Www = o2.getWebmasterHostId().getPunycodeHostname().startsWith("www.");
            if (o1Www != o2Www) {
                if (o1Www == newHostIsWww) {
                    return -1;
                } else {
                    return 1;
                }
            }

            WebmasterHostId.Schema o1Schema = o1.getWebmasterHostId().getSchema();
            WebmasterHostId.Schema o2Schema = o2.getWebmasterHostId().getSchema();
            if (o1Schema != o2Schema) {
                if (o1Schema == hostId.getSchema()) {
                    return -1;
                } else if (o2Schema == hostId.getSchema()) {
                    return 1;
                }
            }

            int o1Port = o1.getWebmasterHostId().getPort();
            int o2Port = o2.getWebmasterHostId().getPort();
            if (o1Port != o2Port) {
                if (o1Port == hostId.getPort()) {
                    return -1;
                } else if (o2Port == hostId.getPort()) {
                    return 1;
                }
            }

            // Если мы добрались сюда - то у нас два хоста, отличающихся только схемой и/или портом.
            // Тупо как-нибудь отсортируем для консистентности
            return (o1Port * 10 + o1Schema.ordinal()) - (o2Port * 10 + o2Schema.ordinal());
        };
    }


    private static String normalizeHost(WebmasterHostId hostId) {
        String result = hostId.getPunycodeHostname();
        if (result.startsWith("www.")) {
            result = result.substring("www.".length());
        }
        return result;
    }
}
