package kr.co.icontrols.ilp300_700.call;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class MyTCPServer {
    private static final String TAG = "TCPServer";
    private static int PORT = 4001;
    private static MyTCPServer mMyTCPServer;

    private TCPServerThread mServerThread;
    private Context mContext;

    private BufferedReader mInputBuffer;
    private BufferedWriter mOutputBuffer;

    private Handler mHandler;

    public MyTCPServer(Context context, Handler handler) {
        mContext = context;
        mHandler = handler;
        Log.d(TAG, "MyTCPServer: ");
    }

    public MyTCPServer(Handler handler) {

        mHandler = handler;
        Log.d(TAG, "MyTCPServer: ");
    }

    public static MyTCPServer getInstance(Context context, Handler handler) {

        Log.d(TAG, "getInstance: ");
        if (mMyTCPServer == null) {
            Log.d(TAG, "getInstance: 1");
            mMyTCPServer = new MyTCPServer(context, handler);
        }

        return mMyTCPServer;
    }

    public void start() {
        if (mServerThread == null) {
            Log.d(TAG, "start(): ");
            mServerThread = new TCPServerThread();
            mServerThread.start();
        }
    }

    public void stop() {
        //if (mServerThread == null) {
            Log.d(TAG, "stop(): ");
            //mServerThread = new TCPServerThread();
            mServerThread.cancel();
            mServerThread = null;

        //}
    }

//    public class TCPServer implements Runnable{
//
//        public static final String SERVERIP = "127.0.0.1";
//        public static final int SERVERPORT = 4001;
//
//        public void run() {
//            try {
//                Log.d("TCP", "S: Connecting...");
//
//                ServerSocket serverSocket = new ServerSocket(SERVERPORT);
//                while (true) {
//                    Socket client = serverSocket.accept();
//                    Log.d("TCP", "S: Receiving...");
//                    try {
//                        BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
//                        char[] str = new char[10];
//                        int a = in.read(str);
//                        Log.d("TCP", "S: Received: '" + str[0] + "' " + a);
//                    } catch(Exception e) {
//                        Log.e("TCP", "S: Error", e);
//                    } finally {
//                        client.close();
//                        Log.d("TCP", "S: Done.");
//                    }
//
//                }
//
//            } catch (Exception e) {
//                Log.e("TCP", "S: Error", e);
//            }
//        }
//    }

    class TCPServerThread extends Thread {
        private Boolean working;
        private ServerSocket mServerSocket;
        private Socket client;
        private String clientIP;
        DataOutputStream output;
        DataInputStream input;

        public TCPServerThread() {
            working = true;
        }

        @Override
        public void run() {
            Thread.currentThread().setName("MyTCPServer");
            try {
                //ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
                //mServerSocket = factory.createServerSocket(PORT);
                Log.d(TAG, "TCPServerThread(): ");
                mServerSocket = new ServerSocket(PORT);

                while(working) {
                    Log.d(TAG, "TCPServerThread(): 1");
                    // 리스닝
                    client = mServerSocket.accept(); // Listens for a connection to be made to this socket and accepts it.
                    client.setTcpNoDelay(true);
                    clientIP = client.getInetAddress().getHostAddress();

                    mOutputBuffer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
                    mInputBuffer = new BufferedReader(new InputStreamReader(client.getInputStream()));



                    while (! client.isClosed()) {
                        Log.d(TAG, "TCPServerThread(): 2 " + clientIP);
                        String data = "";
                        char[] str = new char[100];
                        int len = 0;
                        if ((len = mInputBuffer.read(str)) > 0) {
                            for(int i = 0; i < len; i++)
                            {
                                data += Character.toString(str[i]);
                            }
                            //data = str.toString();
                            Log.d(TAG, "read: " + data);
                            if (data.equals("HEY")) {
                                Log.d(TAG,"[mySocket] HEY ACK()");
                                mOutputBuffer.write("ACK", 0, "ACK".length());
                                mOutputBuffer.flush();

                            }

                            if (data.equals("BYE")) {
                                mOutputBuffer.write("ACK", 0, "ACK".length());
                                mOutputBuffer.flush();

                                Message msg = mHandler.obtainMessage(101, clientIP);
                                mHandler.sendMessage(msg);

                            }

                            if (data.equals("I_AM_HERE")) {
                                Log.d(TAG,"[mySocket] I_AM_HERE()");
                                mOutputBuffer.write("ACK", 0, "ACK".length());
                                mOutputBuffer.flush();
                                Message msg = mHandler.obtainMessage(102, clientIP);
                                mHandler.sendMessage(msg);
//                                Message msg = mHandler.obtainMessage(100, clientIP);
//                                mHandler.sendMessage(msg);
                                //s.close();
                                //break;
                            }else if (data.equals("I_AM_TALKING") || data.equals("I_AM_TALKI")) {
                                Log.d(TAG,"[mySocket] I_AM_TALKING()");
                                mOutputBuffer.write("ACK", 0, "ACK".length());
                                mOutputBuffer.flush();
//                                Message msg = mHandler.obtainMessage(100, clientIP);
//                                mHandler.sendMessage(msg);


                            }
                            else if (data.equals("I_AM_BUSY")) {
                                Log.d(TAG,"[mySocket] I_AM_BUSY()");
                                mOutputBuffer.write("ACK", 0, "ACK".length());
                                mOutputBuffer.flush();
                                Message msg = mHandler.obtainMessage(103, clientIP);
                                mHandler.sendMessage(msg);


                            }
                            else if (data.contains("CALL_REDIRECT_")) {
                                Log.d(TAG,"[mySocket] CALL_REDIRECT_TO_() data " + data);
                                mOutputBuffer.write("ACK", 0, "ACK".length());
                                mOutputBuffer.flush();
                                String[] strReIPSplit = data.split("_");

                                Message msg = mHandler.obtainMessage(104, strReIPSplit[3].trim());
                                mHandler.sendMessage(msg);


                            }


                        }
                        client.close();

                    }
                }


            } catch (IOException e) {
                Log.v(TAG, "Fail TCPServer!!");
                e.printStackTrace();
            }
        }

        public void cancel() {
            working = false;
        }

    }
}
