package ru.yandex.webmaster3.worker.notifications;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import lombok.RequiredArgsConstructor;
import org.joda.time.LocalDate;

import ru.yandex.webmaster3.storage.host.CommonDataType;
import ru.yandex.webmaster3.storage.notifications.dao.EuEmailYDao;
import ru.yandex.webmaster3.storage.settings.SettingsService;

/**
 * WMC-7004
 *
 * @author akhazhoyan 02/2019
 */
@RequiredArgsConstructor
public class EuEmailService {
    private static final String YANDEX_MAIL_DEFAULT_RE = "^((.+)@ya(ndex){0,1}\\.ru$)$";
    private static final String YANDEX_TLD_RE =
            "(" +
                    "(yandex\\.(lv|ee|tm|tj|md|kg|az|lt|fr|uz|ua|kz|com|by|(com\\.(tr|ge|am|ua|ru))|(co\\.il)))" +
                    "|(ya\\.ru)" +
                    ")$";
    private static final String YANDEX_MAIL_FULL_RE = ".+@" + YANDEX_TLD_RE;
    private static final String YANDEX_TLD_REGEXP = "@" + YANDEX_TLD_RE;
    private static final String GOOGLE_MAIL_SUFFIX = "@googlemail.com";

    private final SettingsService settingsService;
    private final EuEmailYDao euEmailYDao;

    public LocalDate lastImportDate() {
        return LocalDate.parse(settingsService.getSettingCached(CommonDataType.LAST_EU_EMAILS_UPDATE).getValue());
    }

    public void setLastImportDate(LocalDate newDate) {
        settingsService.update(CommonDataType.LAST_EU_EMAILS_UPDATE, newDate.toString());
    }


    public boolean isAddressEuropean(String address) {
        if (Strings.isNullOrEmpty(address)) {
            return false;
        }

        return euEmailYDao.contains(normalize(address), lastImportDate());
    }

    /**
     * TODO: есть подозрение, что после переезда в аркадию можно использовать C++ код из джавы.
     * Если нет, то можно заиспользовать JNI.
     * Лучше с этим не затягивать, логика крипты по нормализации может поменяться.
     * Copy of C++ code from https://a.yandex-team.ru/arc/trunk/arcadia/crypta/graph/soup/identifiers/lib/id_types/email.cpp?rev=4455420#L27
     */
    @VisibleForTesting
    static String normalize(String address) {
        String normalized = address.toLowerCase().trim();
        boolean yandexFullMatches = normalized.matches(YANDEX_MAIL_FULL_RE);
        if (yandexFullMatches || normalized.matches(YANDEX_MAIL_DEFAULT_RE)) {
            int index = normalized.indexOf('@');
            String login = normalized.substring(0, index).replace('.', '-');
            normalized = login + normalized.substring(index);
        }
        if (normalized.endsWith(GOOGLE_MAIL_SUFFIX)) {
            String login = normalized.substring(0, normalized.indexOf('@'));
            normalized = login + "@gmail.com";
        }
        if (yandexFullMatches) {
            normalized = normalized.replaceAll(YANDEX_TLD_REGEXP, "@yandex.ru");
        }
        return normalized;
    }
}
