package cn.axzo.msg.center.service.pending;

import cn.axzo.framework.domain.ServiceException;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yanglin
 */
@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class ModelVersion {

    private static final Map<Integer, ModelVersion> VERSIONS = new ConcurrentHashMap<>();
    private static final Integer MAX_VERSION_NUMBER = 500;
    private static final Integer MIN_VERSION_NUMBER = 0;

    public static final ModelVersion V2 = of(null);
    public static final ModelVersion V3 = of(3);
    public static final ModelVersion ALL = of(MAX_VERSION_NUMBER);

    private final Integer versionNumber;

    public static ModelVersion from(ClientRequest request) {
        return of(request == null ? null : request.getModelVersion());
    }

    public static ModelVersion of(Integer version) {
        // attack?
        if (version != null && (version > MAX_VERSION_NUMBER || version < MIN_VERSION_NUMBER))
            throw new ServiceException(String.format("model version is invalid, version=%d", version));
        if (version == null) version = MIN_VERSION_NUMBER;
        return VERSIONS.computeIfAbsent(version, ModelVersion::new);
    }

    public boolean isNot(ModelVersion version) {
        return !is(version);
    }

    public boolean is(ModelVersion version) {
        return Objects.equals(this.versionNumber, version.versionNumber);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ModelVersion)) return false;
        return is((ModelVersion) o);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(versionNumber);
    }

}