package ru.yandex.webmaster3.storage.mobile.data;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import ru.yandex.webmaster3.core.http.HierarchyTypeField;

/**
 * @author avhaliullin
 */
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
        @JsonSubTypes.Type(MobileAuditResult.Success.class),
        @JsonSubTypes.Type(MobileAuditResult.FetchFailedError.class),
        @JsonSubTypes.Type(MobileAuditResult.InternalError.class) }
)
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class MobileAuditResult {
    private final MobileAuditResultType type;

    protected MobileAuditResult(MobileAuditResultType type) {
        this.type = type;
    }

    @HierarchyTypeField
    public MobileAuditResultType getType() {
        return type;
    }

    public static class Success extends MobileAuditResult {
        private final String base64PNGScreenshot;
        private final Indicators indicators;
        private final boolean mobileFriendly;
        private final String alternateUrl;
        private final String replaceUrl;
        private final String exampleAlternateUrl;

        @JsonCreator
        public Success(@JsonProperty("mobileFriendly") boolean mobileFriendly,
                       @JsonProperty("base64PNGScreenshot") String base64PNGScreenshot,
                       @JsonProperty("indicators") Indicators indicators,
                       @JsonProperty("alternateUrl") String alternateUrl,
                       @JsonProperty("replaceUrl") String replaceUrl,
                       @JsonProperty("exampleAlternateUrl") String exampleAlternateUrl) {
            super(MobileAuditResultType.OK);
            this.mobileFriendly = mobileFriendly;
            this.base64PNGScreenshot = base64PNGScreenshot;
            this.indicators = indicators;
            this.alternateUrl = alternateUrl;
            this.replaceUrl = replaceUrl;
            this.exampleAlternateUrl = exampleAlternateUrl;
        }

        public Success(boolean mobileFriendly,
                       String base64PNGScreenshot,
                       Indicators indicators,
                       String replaceUrl) {
            this(mobileFriendly, base64PNGScreenshot, indicators, "", replaceUrl, "");
        }

        public boolean isMobileFriendly() {
            return mobileFriendly;
        }

        public String getBase64PNGScreenshot() {
            return base64PNGScreenshot;
        }

        public Indicators getIndicators() {
            return indicators;
        }

        public String getAlternateUrl() {
            return alternateUrl;
        }

        public String getReplaceUrl() {
            return replaceUrl;
        }

        public String getExampleAlternateUrl() {
            return exampleAlternateUrl;
        }

        @AllArgsConstructor
        @Setter
        @Getter
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class Indicators {

            private boolean hasViewPort;
            private boolean hasNoHorizontalScrolling;
            private boolean hasNoFlash;
            private boolean hasNoApplet;
            private boolean hasNoSilverlight;
            private boolean hasNoMuchSmallText;
            private boolean hasTouchDesktopLink;
            private boolean hasLinkAlternate;

            @JsonCreator
            public Indicators() {
                this.hasNoMuchSmallText = true;
            }
        }
    }

    public static class InternalError extends MobileAuditResult {
        @JsonCreator
        public InternalError() {
            super(MobileAuditResultType.INTERNAL_ERROR);
        }
    }

    public static class FetchFailedError extends MobileAuditResult {
        private final int httpCode;

        public FetchFailedError(@JsonProperty("httpCode") int httpCode) {
            super(MobileAuditResultType.FETCH_FAILED);
            this.httpCode = httpCode;
        }

        public int getHttpCode() {
            return httpCode;
        }
    }
}
