package net.openmob.mobileimsdk.android.core;

import android.os.Handler;
import android.util.Log;

import com.renrenliao.im.im.ImMsgBean;
import com.renrenliao.im.utils.MDateUtils;

import net.openmob.mobileimsdk.android.ClientCoreSDK;

import java.util.concurrent.ConcurrentHashMap;


public class QoS4ReciveDaemon {
    private static final String TAG = QoS4ReciveDaemon.class.getSimpleName();

    private static volatile QoS4ReciveDaemon instance = null;

    public static final int CHECH_INTERVAL = 300000;

    public static final int MESSAGES_VALID_TIME = 600000;

    private ConcurrentHashMap<String, Long> recievedMessages = new ConcurrentHashMap<>();

    private Handler handler = null;

    private Runnable runnable = null;

    private boolean running = false;

    private boolean _excuting = false;

    private boolean init = false;



    public static QoS4ReciveDaemon getInstance() {
        if (instance == null)
            synchronized (QoS4ReciveDaemon.class) {
                if (instance == null) {
                    instance = new QoS4ReciveDaemon();
                }
            }
        return instance;
    }

    public QoS4ReciveDaemon() {
        init();
    }

    private void init() {
        if (this.init)
            return;
        this.handler = new Handler();
        this.runnable = (() -> {
            if (!this._excuting) {
                this._excuting = true;
                if (ClientCoreSDK.DEBUG) {
                    Log.i(TAG, "【IMCORE】【QoS接收方】++++++++++ START 暂存处理线程正在运行中，当前长度" + this.recievedMessages.size() + ".");
                }
                for (String key : this.recievedMessages.keySet()) {
                    Long recievedTime = this.recievedMessages.get(key);
                    long delta = MDateUtils.currentTimMillis() - ((recievedTime == null) ? 0L : recievedTime);
                    if (delta >= MESSAGES_VALID_TIME) {
                        if (ClientCoreSDK.DEBUG) {
                            Log.i(QoS4ReciveDaemon.TAG, "【IMCORE】【QoS接收方】指纹为" + key + "的包已生存" + delta + "ms(最大允许" + 600000 + "ms), 马上将删除之.");
                        }
                        this.recievedMessages.remove(key);
                    }
                }
            }
            if (ClientCoreSDK.DEBUG) {
                Log.i(QoS4ReciveDaemon.TAG, "【IMCORE】【QoS接收方】++++++++++ END 暂存处理线程正在运行中，当前长度" + QoS4ReciveDaemon.this.recievedMessages.size() + ".");
            }

            this._excuting = false;
            this.handler.postDelayed(this.runnable, CHECH_INTERVAL);
        });

        this.init = true;
    }

    public void startup(boolean immediately) {
        stop();
        if (this.recievedMessages != null && this.recievedMessages.size() > 0) {
            for (String key : this.recievedMessages.keySet())
                putImpl(key);
        }
        this.handler.postDelayed(this.runnable, immediately ? 0L : CHECH_INTERVAL);
        this.running = true;

    }

    public void stop() {
        this.handler.removeCallbacks(this.runnable);
        this.running = false;
    }

    public boolean isRunning() {
        return this.running;
    }

    public boolean isInit() {
        return this.init;
    }

    public void addRecieved(ImMsgBean p) {
        addRecieved(p.getFp());
    }

    public void addRecieved(String fingerPrintOfProtocal) {
        if (fingerPrintOfProtocal == null) {
            Log.i(TAG, "【IMCORE】无效的 fingerPrintOfProtocal==null!");
        } else {
            if (this.recievedMessages.containsKey(fingerPrintOfProtocal)) {
                Log.i(TAG, "【IMCORE】【QoS接收方】指纹为" + fingerPrintOfProtocal + "的消息已经存在于接收列表中，该消息重复了（原理可能是对方因未收到应答包而错误重传导致），更新收到时间戳哦.");
            }

            putImpl(fingerPrintOfProtocal);
        }
    }

    private void putImpl(String fingerPrintOfProtocal) {
        if (fingerPrintOfProtocal != null){
            this.recievedMessages.put(fingerPrintOfProtocal, MDateUtils.currentTimMillis());
        }
    }

    public boolean hasRecieved(String fingerPrintOfProtocal) {
        return this.recievedMessages.containsKey(fingerPrintOfProtocal);
    }

    public void clear() {
        this.recievedMessages.clear();
    }

    public int size() {
        return this.recievedMessages.size();
    }

}
