package ru.yandex.webmaster3.api.http.rest.response.errors;

import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.api.http.rest.response.ApiResponse;

import java.util.Collection;
import java.util.Set;

/**
 * @author avhaliullin
 */
public interface CommonApiErrors extends ApiErrorResponse<CommonApiErrors.Code> {
    enum Code implements ApiErrorCode {
        FIELD_VALIDATION_ERROR,
        RESOURCE_NOT_FOUND,
        METHOD_NOT_ALLOWED,
        CONTENT_TYPE_UNSUPPORTED,
        CONTENT_ENCODING_UNSUPPORTED,
        ENTITY_VALIDATION_ERROR,
    }

    @Description("Параметр не прошел валидацию")
    class FieldValidationError extends ApiResponse.BadRequest400<Code> implements CommonApiErrors {
        private final String fieldName;
        private final String fieldValue;

        public FieldValidationError(String reason, String fieldName, String fieldValue) {
            super(Code.FIELD_VALIDATION_ERROR, "Error validating parameter \"" + fieldName + "\": " + reason);
            this.fieldName = fieldName;
            this.fieldValue = fieldValue;
        }

        @Description("Name of field failed validation")
        public String getFieldName() {
            return fieldName;
        }

        @Description("Value passed into field")
        public String getFieldValue() {
            return fieldValue;
        }
    }

    @Description("Запрошенный ресурс не найден")
    class ResourceNotFoundError extends ApiResponse.NotFound404<Code> implements CommonApiErrors {
        public ResourceNotFoundError(String message) {
            super(Code.RESOURCE_NOT_FOUND, message);
        }
    }

    @Description("HTTP-метод не поддерживается для этого ресурса")
    class MethodNotAllowedError extends ApiResponse.MethodNotAllowed405<Code> implements CommonApiErrors {
        public MethodNotAllowedError(Set<String> allowedMethods) {
            super(Code.METHOD_NOT_ALLOWED, allowedMethods);
        }
    }

    @Description("Content-Type'ы, переданные в заголовке Accept, не поддерживаются")
    class NotAcceptableError extends ApiResponse.NotAcceptable406<Code> implements CommonApiErrors {
        public NotAcceptableError(Collection<String> acceptableTypes) {
            super(Code.CONTENT_TYPE_UNSUPPORTED, acceptableTypes);
        }
    }

    @Description("Content-Type запроса не поддерживается")
    class UnsupportedMediaTypeError extends ApiResponse.UnsupportedMediaType415<Code> implements CommonApiErrors {
        private final Set<String> supportedContentTypes;

        public UnsupportedMediaTypeError(Set<String> supportedContentTypes) {
            this(supportedContentTypes, "Unsupported content type");
        }

        public UnsupportedMediaTypeError(Set<String> supportedContentTypes, String message) {
            super(Code.CONTENT_TYPE_UNSUPPORTED, message);
            this.supportedContentTypes = supportedContentTypes;
        }

        @Description("List of supported content types")
        public Set<String> getSupportedContentTypes() {
            return supportedContentTypes;
        }

    }

    @Description("Content-Encoding запроса не поддерживается")
    class UnsupportedContentEncodingError extends ApiResponse.UnsupportedMediaType415<Code> implements CommonApiErrors {
        private final Set<String> supportedContentEncodings;

        public UnsupportedContentEncodingError(Set<String> supportedContentEncodings) {
            super(Code.CONTENT_ENCODING_UNSUPPORTED, "Unsupported content encoding");
            this.supportedContentEncodings = supportedContentEncodings;
        }

        @Description("List of supported content encodings")
        public Set<String> getSupportedContentEncodings() {
            return supportedContentEncodings;
        }
    }

    @Description("Тело запроса не прошло валидацию")
    class EntityValidationError extends BadRequest400<Code> implements CommonApiErrors {
        public EntityValidationError(String message) {
            super(Code.ENTITY_VALIDATION_ERROR, message);
        }
    }
}
