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

import org.jetbrains.annotations.Nullable;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.storage.host.moderation.camelcase.DisplayNameRequest;
import ru.yandex.webmaster3.storage.host.moderation.camelcase.HostDisplayNameModerationRequestState;
import ru.yandex.webmaster3.viewer.http.camelcase.data.BeautyHostName;
import ru.yandex.webmaster3.viewer.http.camelcase.data.DisplayNameRequestView;

/**
* @author aherman
*/
public abstract class ChangeHostDisplayNameResponse implements ActionResponse {
    public static class NormalResponse extends ChangeHostDisplayNameResponse  implements ActionResponse.NormalResponse {
        private final DisplayNameRequestView displayNameRequest;
        private final DisplayNameRequestView pendingDisplayNameRequest;

        public NormalResponse(WebmasterHostId host, @Nullable DisplayNameRequest request,
                              @Nullable BeautyHostName displayName) {
            if (request != null) {
                DisplayNameRequestView view = new DisplayNameRequestView(
                        host,
                        request.getRequestId(),
                        displayName,
                        request.getDisplayName(),
                        request.getState(),
                        request.getCreationDate(),
                        request.getModificationDate());
                if (request.getState() == HostDisplayNameModerationRequestState.ACCEPTED) {
                    this.displayNameRequest = null;
                    this.pendingDisplayNameRequest = view;
                } else {
                    this.displayNameRequest = view;
                    this.pendingDisplayNameRequest = null;
                }
            } else {
                this.displayNameRequest = null;
                this.pendingDisplayNameRequest = null;
            }
        }

        public DisplayNameRequestView getDisplayNameRequest() {
            return displayNameRequest;
        }

        public DisplayNameRequestView getPendingDisplayNameRequest() {
            return pendingDisplayNameRequest;
        }
    }

    public static enum ChangeDisplayNameErrorType {
        CHANGE_DISPLAY_NAME__IDN_HOSTS_ARE_NOT_SUPPORTED,
        CHANGE_DISPLAY_NAME__INVALID_DISPLAY_NAME,
        CHANGE_DISPLAY_NAME__DISPLAY_NAME_IS_THE_SAME,
        CHANGE_DISPLAY_NAME__TOO_MANY_CONSECUTIVE_UPPER_LETTERS,
        CHANGE_DISPLAY_NAME__ALREADY_HAS_MODERATION_REQUEST,
        CHANGE_DISPLAY_NAME__ALREADY_HAS_PENDING_REQUEST
    }

    static abstract class BaseErrorResponse extends ChangeHostDisplayNameResponse implements ActionResponse.ErrorResponse {
        private final Class<?> clazz;
        protected BaseErrorResponse(Class<?> clazz) {this.clazz = clazz;}
        @Override public Class<?> getClazz() {return clazz;}
    }

    public static class IdnHostsAreNotSupportedResponse extends BaseErrorResponse {
        public IdnHostsAreNotSupportedResponse(Class<?> clazz) {
            super(clazz);
        }
        @Override
        public Enum<?> getCode() {
            return ChangeDisplayNameErrorType.CHANGE_DISPLAY_NAME__IDN_HOSTS_ARE_NOT_SUPPORTED;
        }
        @Override
        public String getMessage() {
            return "Idn host names are not supported";
        }
    }

    public static class InvalidDisplayNameResponse extends BaseErrorResponse {
        public InvalidDisplayNameResponse(Class<?> clazz) {
            super(clazz);
        }
        @Override
        public Enum<?> getCode() {
            return ChangeDisplayNameErrorType.CHANGE_DISPLAY_NAME__INVALID_DISPLAY_NAME;
        }
    }

    public static class DisplayNameIsTheSameResponse extends BaseErrorResponse {
        public DisplayNameIsTheSameResponse(Class<?> clazz) {
            super(clazz);
        }
        @Override
        public Enum<?> getCode() {
            return ChangeDisplayNameErrorType.CHANGE_DISPLAY_NAME__DISPLAY_NAME_IS_THE_SAME;
        }
    }

    public static class TooManyConsecutiveUpperLettersResponse extends BaseErrorResponse {
        public TooManyConsecutiveUpperLettersResponse(Class<? extends ChangeHostDisplayNameAction> clazz) {
            super(clazz);
        }

        @Override
        public Enum<?> getCode() {
            return ChangeDisplayNameErrorType.CHANGE_DISPLAY_NAME__TOO_MANY_CONSECUTIVE_UPPER_LETTERS;
        }

        @Override
        public String getMessage() {
            return "Too many consecutive upper letters in domain name part";
        }
    }

    public static class AlreadyHasModerationRequestResponse extends BaseErrorResponse {
        public AlreadyHasModerationRequestResponse(Class<? extends ChangeHostDisplayNameAction> clazz) {
            super(clazz);
        }

        @Override
        public Enum<?> getCode() {
            return ChangeDisplayNameErrorType.CHANGE_DISPLAY_NAME__ALREADY_HAS_MODERATION_REQUEST;
        }

        @Override
        public String getMessage() {
            return "Request in moderation already exists";
        }
    }

    public static class AlreadyHasPendingRequestResponse extends BaseErrorResponse {
        private final String pendingDisplayName;

        public AlreadyHasPendingRequestResponse(String pendingDisplayName, Class<? extends ChangeHostDisplayNameAction> clazz) {
            super(clazz);
            this.pendingDisplayName = pendingDisplayName;
        }

        @Override
        public Enum<?> getCode() {
            return ChangeDisplayNameErrorType.CHANGE_DISPLAY_NAME__ALREADY_HAS_PENDING_REQUEST;
        }

        @Override
        public String getMessage() {
            return "Pending request already exists";
        }

        public String getPendingDisplayName() {
            return pendingDisplayName;
        }
    }
}
