package ru.yandex.webmaster3.storage.turbo.service.autoparser;

import org.apache.commons.lang3.StringUtils;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.turbo.model.TurboSampleData;
import ru.yandex.webmaster3.core.turbo.model.autoparser.AutoparserToggleState;
import ru.yandex.webmaster3.core.turbo.model.autoparser.TurboAutoparsedHostInfo;
import ru.yandex.webmaster3.core.util.WwwUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by ifilippov5 on 22.06.18.
 */
public class TurboAutoparserInfoUtil {

    public static final AutoparserToggleState DEFAULT_AUTOPARSER_CHECKBOX_STATE = AutoparserToggleState.INHERITS;
    public static final int MAX_SAMPLES_COUNT = 10;

    /***
     * На основе таблички от турбо строит списки сэмплов, учитывая сэмплы из поддоменов.
     * Пытаемся для каждого хоста добрать до 10 сэмплов с разных поддоменов.
     */
    public static void pushUpAutoparsedSamples(Map<String, TurboAutoparsedHostInfo> data,
                                               Map<String, String> domains2Owners) {
        List<String> hosts = data.keySet().stream()
                .sorted(Comparator.comparing(String::length).reversed())
                .collect(Collectors.toList());

        //мап: оунер - кол-во уровней в домене - домен - список сэмплов
        Map<String, Map<Integer, Map<String, List<TurboSampleData>>>> samplesFromSubdomains = new HashMap<>();
        for (String host : hosts) {
            String owner = domains2Owners.get(host);
            samplesFromSubdomains.computeIfAbsent(owner, k -> new HashMap<>());
            int levelsCount = getParentsChain(host, owner).size();
            samplesFromSubdomains.get(owner).computeIfAbsent(levelsCount, k -> new TreeMap<>());
            samplesFromSubdomains.get(owner).computeIfAbsent(levelsCount + 1, k -> new TreeMap<>());
            List<TurboSampleData> samples = data.get(host).getSamples();
            int lacks = MAX_SAMPLES_COUNT - samples.size();
            int index = 0;
            while (true) {
                int oldLacks = lacks;
                for (List<TurboSampleData> curSample : samplesFromSubdomains.get(owner).get(levelsCount + 1).values()) { //благодаря TreeMap порядок будет детерминирован
                    if (lacks > 0 && index < curSample.size()) {
                        samples.add(curSample.get(index));
                        lacks--;
                    }
                    if (lacks == 0) {
                        break;
                    }
                }
                if (lacks == 0 || oldLacks == lacks) {
                    break;
                }
                index++;
            }
            samplesFromSubdomains.get(owner).get(levelsCount).put(host, samples);
            TurboAutoparsedHostInfo info = data.get(host);
            data.put(host, info.withSamples(samples));
        }
    }

    public static List<String> getParentsChain(String startDomain, String topDomain) {
        String domain = StringUtils.trimToEmpty(startDomain);
        if (domain.isEmpty() || domain.equals(topDomain)) {
            return Collections.emptyList();
        }
        List<String> tlds = new ArrayList<>();
        String[] hostLevels = StringUtils.trimToEmpty(domain).split("\\.");
        for (int startIndex = 1; startIndex < hostLevels.length - 1; startIndex++) {
            String tld = Arrays
                    .stream(hostLevels)
                    .skip(startIndex)
                    .collect(Collectors.joining("."));
            tlds.add(tld);
            if (tld.equals(topDomain)) {
                break;
            }
        }
        return tlds;
    }

    /***
     * Отрезаем то же, что и в https://a.yandex-team.ru/arc/trunk/arcadia/quality/functionality/content_plugins/scripts/regular_updates/converters/sideblock_hosts_config.py?rev=3773366#L151
     */
    public static String canonizeHost(WebmasterHostId hostId) {
        String domain = hostId.getASCIIHostname();
        if (WwwUtil.isWWW(domain)) {
            return WwwUtil.switchWWW(domain);
        }
        return domain;
    }

}
