package com.jimind.sportdemo.base;

import android.util.MalformedJsonException;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.exceptions.CompositeException;

/**
 * 观察者基类
 *
 * @param <T>
 * @author Any
 */
public abstract class BaseObserver<T> implements Observer<T> {

    private Disposable disposable;
    private static final int CODE_TIMEOUT = 1000;
    private static final int CODE_UNCONNECTED = 1001;
    private static final int CODE_JSON = 1020;
    private static final int CODE_DEFAULT = 1003;

    private static final String CONNECT_EXCEPTION = "网络出现了些许小问题,请检查网络连接";
    private static final String SOCKET_TIMEOUT_EXCEPTION = "网络连接超时，请检查您的网络状态，稍后重试";
    private static final String MALFORMED_JSON_EXCEPTION = "数据解析错误";

    @Override
    public void onSubscribe(Disposable d) {
        disposable = d;
    }

    @Override
    public void onNext(T t) {
        onSuccess(t);
    }

    @Override
    public void onError(Throwable e) {
        if (e instanceof CompositeException) {
            CompositeException compositeE = (CompositeException) e;
            for (Throwable throwable : compositeE.getExceptions()) {
                if (throwable instanceof SocketTimeoutException) {
                    onFailure(CODE_TIMEOUT, SOCKET_TIMEOUT_EXCEPTION);
                } else if (throwable instanceof ConnectException) {
                    onFailure(CODE_UNCONNECTED, CONNECT_EXCEPTION);
                } else if (throwable instanceof UnknownHostException) {
                    onFailure(CODE_UNCONNECTED, CONNECT_EXCEPTION);
                } else if (throwable instanceof MalformedJsonException) {
                    onFailure(CODE_JSON, MALFORMED_JSON_EXCEPTION);
                }
            }
        } else {
            onFailure(CODE_DEFAULT, e.getMessage());
        }
        close();
    }

    @Override
    public void onComplete() {
        close();
    }

    private void close() {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
            disposable = null;
        }
    }

    /**
     * 请求成功
     *
     * @param t
     */
    protected abstract void onSuccess(T t);

    /**
     * 请求失败
     *
     * @param code
     * @param message
     */
    protected abstract void onFailure(int code, String message);
}
