package ru.yandex.webmaster3.api.searchurls.data;

import org.jetbrains.annotations.Nullable;
import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.sitestructure.SearchUrlStatusEnum;

import java.util.EnumMap;
import java.util.Map;

import static ru.yandex.webmaster3.core.sitestructure.SearchUrlStatusEnum.INDEXED_SEARCHABLE;
import static ru.yandex.webmaster3.core.sitestructure.SearchUrlStatusEnum.REDIRECT_SEARCHABLE;

/**
 * @author avhaliullin
 */
public enum ApiExcludedUrlStatusEnum {
    @Deprecated
    @Description("Роботу неизвестно о странице или она длительное время была недоступна. Сообщите о странице с помощью инструмента в Вебмастере, в течение 1-2 недель она проиндексируется.")
    NOTHING_FOUND(SearchUrlStatusEnum.NOTHING_FOUND),
    @Description("При обращении к сайту роботу не удалось установить соединение с сервером. Проверьте ответ сервера, убедитесь в отсутствии блокировки нашего робота на стороне провайдера. Сайт начнет индексироваться автоматически, если станет доступным для робота.")
    HOST_ERROR(SearchUrlStatusEnum.HOST_ERROR),
    @Description("Страница осуществляет перенаправление, при котором индексируется его цель (RedirectTarget). Проверьте индексирование страницы, на которую выполняется редирект.")
    REDIRECT_NOTSEARCHABLE(SearchUrlStatusEnum.REDIRECT_NOTSEARCHABLE),
    @Description("При обращении к странице возникла ошибка HTTP-ошибка. Проверьте ответ сервера. Если проблема актуальна, обратитесь к администратору своего сайта или сервера. Если страница уже доступна, отправьте её на переобход.")
    HTTP_ERROR(SearchUrlStatusEnum.HTTP_ERROR),
    @Description("Страница проиндексирована по каноническому адресу, который был указан в атрибуте rel=\"canonical\" в её исходном коде. Исправьте или удалите атрибут canonical, если он указан некорректно. Робот отследит изменения автоматически.")
    NOT_CANONICAL(SearchUrlStatusEnum.NOT_CANONICAL),
    @Description("Страница относится к неглавному зеркалу сайта, поэтому была исключена из поиска.")
    NOT_MAIN_MIRROR(SearchUrlStatusEnum.NOT_MAIN_MIRROR),
    @Description("При обращении к странице роботу не удалось получить ее содержимое. Проверьте ответ сервера или наличие запрещающих HTML-тегов. Если проблема актуальна, обратитесь к администратору своего сайта или сервера. Если страница уже доступна, отправьте её на переобход.")
    PARSER_ERROR(SearchUrlStatusEnum.PARSER_ERROR),
    @Description("Индексирование сайта запрещено в файле robots.txt. Робот автоматически начнет посещать страницу, когда сайт станет доступен для индексирования.")
    ROBOTS_HOST_ERROR(SearchUrlStatusEnum.ROBOTS_HOST_ERROR),
    @Description("Индексирование страницы запрещено в robots.txt. Робот автоматически начнет посещать страницу, когда она станет доступной для индексирования.")
    ROBOTS_URL_ERROR(SearchUrlStatusEnum.ROBOTS_URL_ERROR),
    @Description("Страница дублирует уже представленную в поиске страницу сайта. Укажите роботу предпочтительный адрес с помощью 301 редиректа или атрибута canonical. Если содержимое страниц различается, добавьте их на переобход, чтобы ускорить обновление данных в поисковой базе.")
    DUPLICATE(SearchUrlStatusEnum.SEMIDUP),
    @Description("Страница отсутствует в поиске в результате работы алгоритма. Если алгоритм сочтет страницу достаточно релевантной запросам пользователей, она появится в поиске автоматически")
    LOW_QUALITY(SearchUrlStatusEnum.SR),
    @Description("Страница была исключена из поиска в результате обработки роботом директивы Clean-param. Чтобы страница индексировалась, измените robots.txt")
    CLEAN_PARAMS(SearchUrlStatusEnum.CLEAN_PARAMS),
    @Description("Страница исключена из-за тега noindex")
    NO_INDEX(SearchUrlStatusEnum.NO_INDEX),
    @Description("Неподдерживаемый формат документа")
    BAD_MIME_TYPE(SearchUrlStatusEnum.BAD_MIME_TYPE),
    @Description("У робота нет актуальных данных для страницы. Проверьте ответ сервера или наличие запрещающих HTML-тегов. Если проблема актуальна, обратитесь к администратору своего сайта или сервера. Если страница уже доступна, отправьте её на переобход.")
    OTHER(SearchUrlStatusEnum.OTHER),
    ;

    private SearchUrlStatusEnum coreStatus;

    ApiExcludedUrlStatusEnum(SearchUrlStatusEnum coreStatus) {
        this.coreStatus = coreStatus;
    }

    private static final Map<SearchUrlStatusEnum, ApiExcludedUrlStatusEnum> CORE_STATUS_2_API_STATUS =
        new EnumMap<>(SearchUrlStatusEnum.class);

    static {
        for (ApiExcludedUrlStatusEnum status : values()) {
            CORE_STATUS_2_API_STATUS.put(status.coreStatus, status);
        }
    }

    /**
     * SearchUrlStatusEnum содержит статусы и для страниц в поиске,
     * поэтому этот метод вполне законно может вернуть null
     */
    @Nullable
    public static ApiExcludedUrlStatusEnum fromCoreStatus(SearchUrlStatusEnum coreStatus) {
        // страница в поиске
        if (coreStatus == INDEXED_SEARCHABLE || coreStatus == REDIRECT_SEARCHABLE) {
            return null;
        }

        // остальные статусы должно быть замаплены
        ApiExcludedUrlStatusEnum apiStatus;
        switch (coreStatus) {
            case INDEXED_NOTSEARCHABLE:
                apiStatus = DUPLICATE;
                break;

            default:
                apiStatus = CORE_STATUS_2_API_STATUS.get(coreStatus);
                break;
        }

        if (apiStatus == null) {
            throw new RuntimeException("Unexpected core status: " + coreStatus);
        }

        return apiStatus;
    }
}
