package ru.yandex.webmaster3.viewer.http.indexing;

import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;
import ru.yandex.webmaster3.core.codes.DownloadedHttpCodeGroup;
import ru.yandex.webmaster3.core.codes.ErrorGroupEnum;
import ru.yandex.webmaster3.storage.history.IndexingIndicatorEnum;

/**
 * @author aherman
 */
public class IndexingIndicator {
    public enum All {
        INDEXING,
        INDEXING_SEARCHABLE,
        INDEXING_DOWNLOADED,
        INDEXING_DOWNLOADED_2XX,
        INDEXING_DOWNLOADED_3XX,
        INDEXING_DOWNLOADED_4XX,
        INDEXING_DOWNLOADED_5XX,
        INDEXING_DOWNLOADED_INCORRECT_RESPONSE,
        INDEXING_DOWNLOADED_COULD_NOT_DOWNLOAD,
        INDEXING_EXCLUDED,
        INDEXING_EXCLUDED_SITE_ERRORS,
        INDEXING_EXCLUDED_DISALLOWED_BY_USER,
        INDEXING_EXCLUDED_UNSUPPORTED_BY_ROBOT
    }

    public enum Miscelanous {
        INDEXING_TCI,
        INDEXING_SQI
    }

    public enum Indexing {
        INDEXING_SEARCHABLE(All.INDEXING_SEARCHABLE),
        INDEXING_DOWNLOADED(All.INDEXING_DOWNLOADED),
        INDEXING_EXCLUDED(All.INDEXING_EXCLUDED),
        INDEXING_DOWNLOADED_COULD_NOT_DOWNLOAD(All.INDEXING_DOWNLOADED_COULD_NOT_DOWNLOAD)
        ;
        private Indexing(All globalIndicator) {
            this.globalIndicator = globalIndicator;
        }
        private final All globalIndicator;
        public All getGlobalIndicator() {
            return globalIndicator;
        }
    }

    public enum Downloaded {
        INDEXING_DOWNLOADED_2XX(All.INDEXING_DOWNLOADED_2XX),
        INDEXING_DOWNLOADED_3XX(All.INDEXING_DOWNLOADED_3XX),
        INDEXING_DOWNLOADED_4XX(All.INDEXING_DOWNLOADED_4XX),
        INDEXING_DOWNLOADED_5XX(All.INDEXING_DOWNLOADED_5XX),
        //INDEXING_DOWNLOADED_INCORRECT_RESPONSE(All.INDEXING_DOWNLOADED_INCORRECT_RESPONSE),
        INDEXING_DOWNLOADED_COULD_NOT_DOWNLOAD(All.INDEXING_DOWNLOADED_COULD_NOT_DOWNLOAD)
        ;
        private Downloaded(All globalIndicator) {
            this.globalIndicator = globalIndicator;
        }
        private final All globalIndicator;
        public All getGlobalIndicator() {
            return globalIndicator;
        }
    }

    public enum Excluded {
        INDEXING_EXCLUDED_SITE_ERRORS(All.INDEXING_EXCLUDED_SITE_ERRORS),
        INDEXING_EXCLUDED_DISALLOWED_BY_USER(All.INDEXING_EXCLUDED_DISALLOWED_BY_USER),
        INDEXING_EXCLUDED_UNSUPPORTED_BY_ROBOT(All.INDEXING_EXCLUDED_UNSUPPORTED_BY_ROBOT),
        ;
        private Excluded(All globalIndicator) {
            this.globalIndicator = globalIndicator;
        }
        private final All globalIndicator;
        public All getGlobalIndicator() {
            return globalIndicator;
        }
    }

    public static IndexingIndicatorEnum toIndicator(Indexing indicator) {
        switch (indicator) {
            case INDEXING_SEARCHABLE: return IndexingIndicatorEnum.SEARCH_DOCS_COUNT;
            case INDEXING_DOWNLOADED: return IndexingIndicatorEnum.DOWNLOADED_DOCS_COUNT;
            case INDEXING_EXCLUDED: return IndexingIndicatorEnum.EXCLUDED_PAGES_COUNT;
        }

        throw new WebmasterException("Missing indicator: " + indicator,
                new WebmasterErrorResponse.InternalUnknownErrorResponse(IndexingIndicator.class,
                        "Missing indicator: " + indicator));
    }

    public static Indexing fromIndicator(IndexingIndicatorEnum indicator) {
        switch(indicator) {
            case DOWNLOADED_DOCS_COUNT: return IndexingIndicator.Indexing.INDEXING_DOWNLOADED;
            case EXCLUDED_PAGES_COUNT: return IndexingIndicator.Indexing.INDEXING_EXCLUDED;
            case SEARCH_DOCS_COUNT: return IndexingIndicator.Indexing.INDEXING_SEARCHABLE;
            case THEMATIC_CITATION_INDEX: return null;
        }

        throw new WebmasterException("Missing indicator: " + indicator,
                new WebmasterErrorResponse.InternalUnknownErrorResponse(IndexingIndicator.class,
                        "Missing indicator: " + indicator));
    }

    public static DownloadedHttpCodeGroup toGroup(Downloaded indicator) {
        switch (indicator) {
            case INDEXING_DOWNLOADED_2XX: return DownloadedHttpCodeGroup.DOWNLOADED_2XX;
            case INDEXING_DOWNLOADED_3XX: return DownloadedHttpCodeGroup.DOWNLOADED_3XX;
            case INDEXING_DOWNLOADED_4XX: return DownloadedHttpCodeGroup.DOWNLOADED_4XX;
            case INDEXING_DOWNLOADED_5XX: return DownloadedHttpCodeGroup.DOWNLOADED_5XX;
            case INDEXING_DOWNLOADED_COULD_NOT_DOWNLOAD: return DownloadedHttpCodeGroup.DOWNLOADED_COULD_NOT_DOWNLOAD;
        }

        throw new WebmasterException("Missing indicator: " + indicator,
                new WebmasterErrorResponse.InternalUnknownErrorResponse(IndexingIndicator.class,
                        "Missing indicator: " + indicator));
    }

    public static Downloaded fromGroup(DownloadedHttpCodeGroup group) {
        switch (group) {
            case DOWNLOADED_2XX: return Downloaded.INDEXING_DOWNLOADED_2XX;
            case DOWNLOADED_3XX: return Downloaded.INDEXING_DOWNLOADED_3XX;
            case DOWNLOADED_4XX: return Downloaded.INDEXING_DOWNLOADED_4XX;
            case DOWNLOADED_5XX: return Downloaded.INDEXING_DOWNLOADED_5XX;
            case DOWNLOADED_COULD_NOT_DOWNLOAD: return Downloaded.INDEXING_DOWNLOADED_COULD_NOT_DOWNLOAD;
        }

        throw new WebmasterException("Missing group: " + group,
                new WebmasterErrorResponse.InternalUnknownErrorResponse(IndexingIndicator.class,
                        "Missing group: " + group));
    }

    public static ErrorGroupEnum toGroup(Excluded indicator) {
        switch (indicator) {
            case INDEXING_EXCLUDED_DISALLOWED_BY_USER: return ErrorGroupEnum.DISALLOWED_BY_USER;
            case INDEXING_EXCLUDED_SITE_ERRORS: return ErrorGroupEnum.SITE_ERROR;
            case INDEXING_EXCLUDED_UNSUPPORTED_BY_ROBOT: return ErrorGroupEnum.UNSUPPORTED_BY_ROBOT;
        }

        throw new WebmasterException("Missing indicator: " + indicator,
                new WebmasterErrorResponse.InternalUnknownErrorResponse(IndexingIndicator.class,
                        "Missing indicator: " + indicator));
    }

    public static Excluded fromGroup(ErrorGroupEnum group) {
        switch (group) {
            case DISALLOWED_BY_USER: return Excluded.INDEXING_EXCLUDED_DISALLOWED_BY_USER;
            case SITE_ERROR: return Excluded.INDEXING_EXCLUDED_SITE_ERRORS;
            case UNSUPPORTED_BY_ROBOT: return Excluded.INDEXING_EXCLUDED_UNSUPPORTED_BY_ROBOT;
        }

        throw new WebmasterException("Missing group: " + group,
                new WebmasterErrorResponse.InternalUnknownErrorResponse(IndexingIndicator.class,
                        "Missing group: " + group));
    }
}
