package springfox.documentation.schema;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import springfox.documentation.service.VendorExtension;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 覆盖 springfox-core 3.0.0 同名类，修复 id 为 null 时 {@link #equals(Object)} NPE（Issue #3989/#4003）。
 */
@JsonInclude(Include.NON_EMPTY)
public class Example {

    private final String id;
    private final String summary;
    private final String description;
    private final Object value;
    private final String externalValue;
    private final String mediaType;
    private final List<VendorExtension> extensions = new ArrayList<>();

    @Deprecated
    public Example(Object value) {
        this.value = value;
        this.mediaType = null;
        this.externalValue = null;
        this.id = null;
        this.summary = null;
        this.description = null;
    }

    @Deprecated
    public Example(String mediaType, Object value) {
        this.mediaType = mediaType;
        this.value = value;
        this.externalValue = null;
        this.id = null;
        this.summary = null;
        this.description = null;
    }

    public Example(String id, String summary, String description, Object value, String externalValue,
            String mediaType) {
        this.id = id;
        this.summary = summary;
        this.description = description;
        this.value = value;
        this.externalValue = externalValue;
        this.mediaType = mediaType;
    }

    public String getId() {
        return id;
    }

    public String getSummary() {
        return summary;
    }

    public String getDescription() {
        return description;
    }

    public String getExternalValue() {
        return externalValue;
    }

    public List<VendorExtension> getExtensions() {
        return extensions;
    }

    public Object getValue() {
        return value;
    }

    public Optional<String> getMediaType() {
        return Optional.ofNullable(mediaType);
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Example example = (Example) o;
        return Objects.equals(id, example.id)
                && Objects.equals(summary, example.summary)
                && Objects.equals(description, example.description)
                && Objects.equals(value, example.value)
                && Objects.equals(externalValue, example.externalValue)
                && Objects.equals(mediaType, example.mediaType)
                && Objects.equals(extensions, example.extensions);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, summary, description, value, externalValue, mediaType, extensions);
    }
}
