package kr.co.icontrols.ilp300_700.rfreader;

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

import kr.co.icontrols.ilp300_700.ethernet.iMAPCommon.iMAPResult;
import kr.co.icontrols.ilp300_700.global.Declare.MultiReaderPacket;
import kr.co.icontrols.ilp300_700.global.Global;
import kr.co.icontrols.ilp300_700.rfreader.HDCStandardManager.MultiRFResultListener;
import kr.co.icontrols.ilp300_700.serialport.HDCStandardReaderSerial;

public class SendNWaitMultiRF implements MultiRFResultListener {

    String TAG = "SendNWaitMultiRF";

    public final int HANDLE_MSG_DONE_REPLY = 100;
    public final int HANDLE_MSG_DONE_SEND = 200;
    public final int HANDLE_MSG_ING = 300;
    public final int HANDLE_MSG_UNREACHABLE = 400;
    public final int HANDLE_MSG_TIMEOUT = 500;
    public final int HANDLE_MSG_ERROR_SEND = 600;
    public final int HANDLE_MSG_ERROR_READ = 700;
    public final int HANDLE_MSG_ERROR_XML = 800;
    public final int HANDLE_MSG_ERROR_OTHER = 900;
    public final int HANDLE_MSG_STOP_THREAD = 1000;
    public int SOCKET_BUFFER_SIZE_SEND = 50;
    public int SOCKET_BUFFER_SIZE_RECEIVE = 50;
    public int SOCKET_BUFFER_SIZE_READ = 50;
    public int TIMEOUT_SOCKET_CONNECT = 5000;
    public int TIMEOUT_SERIAL_REPLY = 2000;   // Request 후 Reply 대기 시간
    public String strReplyResult = "NONE";

    boolean bLOG = true;   // true, false
    boolean bLOG_DEBUG = false;   // true, false
    boolean bLOG_INFO = true;   // true, false
    SendNWaitMultiRFThread mSendNWaitMultiRFThread;
    Handler SendNWaitHandler = new Handler(Looper.getMainLooper()) {
        public void handleMessage(Message msg) {
            LOG_DEBUG("SendNWaitHandler : " + msg.what);
            switch (msg.what) {
                case HANDLE_MSG_DONE_REPLY:
                    onProcessDone(iMAPResult.RcvDone);
                    break;

                case HANDLE_MSG_DONE_SEND:
                    onProcessDone(iMAPResult.SendOK);
                    break;

                case HANDLE_MSG_ING:
                    onProcessDoing();
                    break;

                case HANDLE_MSG_UNREACHABLE:
                    onProcessDone(iMAPResult.Unreachable);
                    break;

                case HANDLE_MSG_TIMEOUT:
                    onProcessDone(iMAPResult.Timeout);
                    break;

                case HANDLE_MSG_ERROR_SEND:
                    onProcessDone(iMAPResult.SendFailure);
                    break;

                case HANDLE_MSG_ERROR_READ:
                    onProcessDone(iMAPResult.ReplyHasFault);
                    break;

                case HANDLE_MSG_ERROR_XML:
                    onProcessDone(iMAPResult.Parcel);
                    break;

                case HANDLE_MSG_ERROR_OTHER:
                    onProcessDone(iMAPResult.Other);
                    break;

                case HANDLE_MSG_STOP_THREAD:
                    stopReplyThread();
                    break;

                default:
                    onProcessDone(iMAPResult.Other);
                    break;
            }
        }
    };

    public SendNWaitMultiRF() {
        try {
            LOG("[SendNWaitMultiRF] ===== START =====");
        } catch (Exception e) {
            Log.e(TAG, "[Exception] SendNWaitMultiRF()");
            e.printStackTrace();
        }
    }

    private void LOG(String log) {
        if (bLOG) Log.v(TAG, log);
    }

    private void LOG_DEBUG(String log) {
        if (bLOG_DEBUG) Log.d(TAG, log);
    }

    private void LOG_INFO(String log) {
        if (bLOG_INFO) Log.i(TAG, log);
    }

    public boolean sendNwaitMSG(byte hReplyCmd, byte[] hData, boolean bReply) {
        try {
            LOG_DEBUG("[sendNwaitMSG] hReplyCmd [" + hReplyCmd + "], bReply [" + bReply + "]");
            LOG_DEBUG("[sendNwaitMSG] hData = " + Global.printHexs(hData));
            return procSendMGS(hReplyCmd, hData, bReply);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] sendNwaitMSG(hReplyCmd, hData, bReply)");
            e.printStackTrace();
            return false;
        }
    }

    public boolean procSendMGS(byte hReplyCmd, byte[] hData, boolean bReply) {
        try {
            LOG_DEBUG("[procSendMGS] hReplyCmd [" + hReplyCmd + "], bReply [" + bReply + "]");
            LOG_DEBUG("[procSendMGS] hData = " + Global.printHexs(hData));
            strReplyResult = "NONE";
            if (bReply) {
                HDCStandardManager.setMultiRFResultListener(this);
                mSendNWaitMultiRFThread = new SendNWaitMultiRFThread(hReplyCmd, SendNWaitHandler);
                mSendNWaitMultiRFThread.start();
            }

            if (!HDCStandardReaderSerial.sendPacketMsg(hData)) {
                Log.w(TAG, "[procSendMGS] Fail to send packet msg at sendPacketMsg(hData)");
                stopReplyThread();
                onProcessDone(iMAPResult.SendFailure);
            }
            return true;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] procSendMGS(hCmd, hReplyCmd, hData, bReply)");
            e.printStackTrace();
            return false;
        }
    }

    protected void onProcessDoing() {
    }

    protected void onProcessDone(iMAPResult eResult) {
    }

    private void stopReplyThread() {
        try {
            LOG("[stopReplyThread] ===== START =====");
            HDCStandardManager.releaseMultiRFResultListener();
            if (mSendNWaitMultiRFThread != null) mSendNWaitMultiRFThread.interrupt();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] stopReplyThread()");
            e.printStackTrace();
        }
    }

    @Override
    public void onReplyResult(String strResult) {
        try {
            LOG("[onReplyResult] strResult = " + strResult);
            strReplyResult = strResult;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onReplyResult(strResult)");
            e.printStackTrace();
        }
    }

    public class SendNWaitMultiRFThread extends Thread {
        long lSocketConnectionPeriod = 0;
        byte hExpectdReplyCmd = 0x00;
        Handler SWHandler;

        public SendNWaitMultiRFThread(byte hReplyCmd, Handler Handle) {
            try {
                LOG("[SendNWaitFPReaderThread] hReplyCmd [" + Global.HextoString(hReplyCmd) + "]");
                hExpectdReplyCmd = hReplyCmd;
                SWHandler = Handle;
            } catch (Exception e) {
                Log.e(TAG, "[Exception] SendNWaitFPReaderThread(hReplyCmd, Handle)");
                e.printStackTrace();
            }
        }

        private void sendHandlerMsg(int msg) {
            try {
                LOG("[sendHandlerMsg] msg : " + msg);
                Message HandleMsg = SWHandler.obtainMessage();
                HandleMsg.what = msg;
                SWHandler.sendMessage(HandleMsg);
            } catch (Exception e) {
                Log.e(TAG, "[Exception] sendHandlerMsg(msg)");
                e.printStackTrace();
            }
        }

        public void run() {
            try {
                LOG("[SendNWaitFPReaderThread.run()] ===== START =====");
                lSocketConnectionPeriod = System.currentTimeMillis() + TIMEOUT_SERIAL_REPLY;   // 타임아웃시간을 설정한다.
                while (System.currentTimeMillis() < lSocketConnectionPeriod) {
                    LOG_INFO("[SendNWaitFPReaderThread.run()] hExpectdReplyCmd [" + Global.HextoString(hExpectdReplyCmd) + "]");
                    if (!strReplyResult.equals("NONE")) {
                        LOG_INFO("[SendNWaitFPReaderThread.run()] strReplyResult [" + strReplyResult + "]");
                        if (hExpectdReplyCmd == MultiReaderPacket.CMD_STATUS_REPLY) {
                            if (strReplyResult.equals("STATUS_OK")) {
                                sendHandlerMsg(HANDLE_MSG_DONE_REPLY);
                                sendHandlerMsg(HANDLE_MSG_STOP_THREAD);
                                return;
                            }
                        } else if (hExpectdReplyCmd == MultiReaderPacket.CMD_FW_VER_REPLY) {
                            if (strReplyResult.contains("FWVER_")) {
                                sendHandlerMsg(HANDLE_MSG_DONE_REPLY);
                                sendHandlerMsg(HANDLE_MSG_STOP_THREAD);
                                return;
                            }
                        } else if (hExpectdReplyCmd == MultiReaderPacket.CMD_ZIGBEE_SENSITIVITY_REPLY) {
                            if ((-100 <= Integer.parseInt(strReplyResult)) && (Integer.parseInt(strReplyResult) <= 100)) {
                                sendHandlerMsg(HANDLE_MSG_DONE_REPLY);
                                sendHandlerMsg(HANDLE_MSG_STOP_THREAD);
                                return;
                            }
                        }
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        Log.e(TAG, "[InterruptedException] (SerialDataReceiver.run()) Thread.sleep(100)");
                        e.printStackTrace();
                    }
                }
                sendHandlerMsg(HANDLE_MSG_TIMEOUT);
                sendHandlerMsg(HANDLE_MSG_STOP_THREAD);
                return;
            } catch (Exception e) {
                Log.e(TAG, "[Exception] (SendNWaitFPReaderThread.run())");
                e.printStackTrace();
                sendHandlerMsg(HANDLE_MSG_ERROR_OTHER);
                sendHandlerMsg(HANDLE_MSG_STOP_THREAD);
            }
        }
    }

}
