package iku.os.net;

import android.content.Context;
import android.provider.Settings;
import android.util.Log;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONArray;
import org.json.JSONObject;

import java.net.URI;

public class IkuClient {
    private static final String TAG = "IkuClient";
    private static IkuClient instance;
    public static IkuClient getInstance()
    {
        if (instance == null)
            instance = new IkuClient();
        return instance;
    }
    private WebSocketClient webSocketClient;

    private String deviceId;
    private boolean initialized = false;

    private boolean connected = false;

    private IkuClientListener listener;
    private IkuClient()
    {
    }

    public void sendMsg(String cmd, JSONArray data)
    {
        sendMsg(cmd, data.toString());
    }
    public void sendMsg(String cmd, JSONObject data)
    {
        sendMsg(cmd, data.toString());
    }
    public void sendMsg(String cmd, String data)
    {
        if (webSocketClient != null && webSocketClient.isOpen())
        {
            try {
                JSONObject msg = new JSONObject();
                msg.put("cmd", cmd);
                msg.put("data", data);

                webSocketClient.send(msg.toString());
            }
            catch (Throwable e)
            {
                status(e.toString());
            }
        }
    }

    public void init(Context context, IkuClientListener listener)
    {
        if (initialized)
            return;
        this.initialized = true;
        this.listener = listener;

        this.deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
    }
    public String getDeviceId()
    {
        return deviceId;
    }
    private void msgReceived(JSONObject msg)
    {
        if (listener != null)
            listener.onData(msg);
    }
    private void stateChanged(boolean connected)
    {
        if (listener != null)
            listener.onStateChanged(connected);
    }
    private void connected()
    {
        if (listener != null)
            listener.onConnected();
    }
    private void status(String msg)
    {
        if (listener != null)
            listener.onStatusLog(msg);
    }

    public URI getConnectedURI()
    {
        return webSocketClient.getURI();
    }

    public void connect(String url)
    {
        try {
            if (webSocketClient != null)
                webSocketClient.close();

            URI uri = new URI(url);
            String scheme = uri.getScheme().toLowerCase();
            String other = uri.getSchemeSpecificPart();
            uri = new URI(scheme + ":" + other);
            webSocketClient = new WebSocketClient(uri) {
                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    Log.i(TAG, "onOpen");

                    connected = true;
                    sendMsg("handshark", "I am device, id=" + getDeviceId());
                    stateChanged(true);
                }

                @Override
                public void onMessage(String message) {
                    Log.i(TAG, "onMessage " + message);
                    try {
                        JSONObject msg = new JSONObject(message);
                        String cmd = msg.getString("cmd");
                        String data = msg.getString("data");
                        if (cmd.equals("handshark"))
                        {
                            status("连接服务器成功!!!");
                            connected();
                        }
                        else {
                            msgReceived(msg);
                        }
                    }
                    catch (Throwable e)
                    {
                        status(e.toString());
                    }
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    Log.i(TAG, "onClose " + reason);
                    if (!connected)
                    {
                        status("无法连接到服务器...");
                    }
                    else {
                        status("连接已断开...");
                    }
                    connected = false;
                    stateChanged(false);
                }

                @Override
                public void onError(Exception ex) {
                    Log.e(TAG, "onError " + ex.toString());
                    status("出现错误 " + ex.toString());
                }
            };
            webSocketClient.connect();
        } catch (Throwable e) {
            status(e.toString());
        }
    }

    public void disconnect() {
        webSocketClient.close();
    }

    public void destroy() {
        if (webSocketClient != null && webSocketClient.isOpen())
            webSocketClient.close();

        webSocketClient = null;
        listener = null;
    }

    public boolean isConnected() {
        if (webSocketClient == null)
            return false;
        return webSocketClient.isOpen();
    }

    public interface IkuClientListener {
        void onStatusLog(String msg);
        void onData(JSONObject data);

        void onStateChanged(boolean connected);

        void onConnected();
    }
}
