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

import java.net.URL;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.joda.time.DateTime;

import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.data.HttpCodeInfo;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.http.response.URLPrettySerializer;
import ru.yandex.webmaster3.storage.mobile.data.MobileAuditRequestState;
import ru.yandex.webmaster3.storage.mobile.data.MobileAuditResult;
import ru.yandex.webmaster3.core.mobile.data.ScreenshotResolution;
import ru.yandex.wmtools.common.util.http.YandexHttpStatus;

/**
 * @author avhaliullin
 */
public abstract class MobileAuditInfoResponse implements ActionResponse {
    public static class NormalResponse extends MobileAuditInfoResponse implements ActionResponse.NormalResponse{
        private final long requestsForHostLeft;
        private final DateTime createdAt;
        private final MobileAuditRequestState state;
        private final URL url;
        private final MobileAuditResult.Success result;
        private final ScreenshotResolution resolution;

        public NormalResponse(long requestsForHostLeft, DateTime createdAt, MobileAuditRequestState state, URL url,
                              ScreenshotResolution resolution, MobileAuditResult.Success result) {
            this.requestsForHostLeft = requestsForHostLeft;
            this.createdAt = createdAt;
            this.state = state;
            this.url = url;
            this.result = result;
            this.resolution = resolution;
        }

        public long getRequestsForHostLeft() {
            return requestsForHostLeft;
        }

        public DateTime getCreatedAt() {
            return createdAt;
        }

        public MobileAuditRequestState getState() {
            return state;
        }

        @JsonSerialize(using = URLPrettySerializer.class)
        public URL getUrl() {
            return url;
        }

        public MobileAuditResult.Success getResult() {
            return result;
        }

        public ScreenshotResolution getResolution() {
            return resolution;
        }
    }

    public enum ErrorCode {
        MOBILE_AUDIT_INFO__INTERNAL_ERROR,
        MOBILE_AUDIT_INFO__REQUEST_NOT_FOUND,
        MOBILE_AUDIT_INFO__FETCH_FAILED,
    }

    public abstract static class AbstractMobileAuditErrorResponse extends MobileAuditInfoResponse implements ActionResponse.ErrorResponse{
        private final ErrorCode code;

        public AbstractMobileAuditErrorResponse(ErrorCode code) {
            this.code = code;
        }

        @Override public Enum<?> getCode() { return code; }
    }

    @Description("Неизвестная ошибка при проверке документа")
    public static class InternalErrorResponse extends AbstractMobileAuditErrorResponse{
        public InternalErrorResponse() {
            super(ErrorCode.MOBILE_AUDIT_INFO__INTERNAL_ERROR);
        }
    }

    @Description("Заявка с указанным id не найдена")
    public static class RequestNotFoundResponse extends AbstractMobileAuditErrorResponse{
        public RequestNotFoundResponse() {
            super(ErrorCode.MOBILE_AUDIT_INFO__REQUEST_NOT_FOUND);
        }
    }

    @Description("Не удалось скачать указанный документ")
    public static class UrlFetchFailedResponse extends AbstractMobileAuditErrorResponse {
        private final YandexHttpStatus httpStatus;
        private final HttpCodeInfo httpCodeInfo;
        private final int extendedHttpCode;
        public UrlFetchFailedResponse(int httpCode) {
            super(ErrorCode.MOBILE_AUDIT_INFO__FETCH_FAILED);
            this.extendedHttpCode = httpCode;
            this.httpCodeInfo = new HttpCodeInfo(httpCode);
            this.httpStatus = YandexHttpStatus.parseCode(httpCode);
        }

        public HttpCodeInfo getHttpCodeInfo() {
            return httpCodeInfo;
        }

        @Description("Роботный статус ответа")
        public YandexHttpStatus getHttpStatus() {
            return httpStatus;
        }

        @Description("Роботный (расширенный) http-код")
        public int getExtendedHttpCode() {
            return extendedHttpCode;
        }
    }
}
