package cn.tee3.avd;
/**
 * Created by bob.liu on 2016/4/24.
 */
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import java.util.List;

/**
 * 外呼设备接入管理接口.
 *
 * 外呼设备接入管理定义引擎中房间呼叫rtsp流，h323和sip设备等功能。
 * 同一房间内，同一user_address只有一个呼入；不同房间中，同一user_address的呼入可以同时存在。
 */
public class AVDOutgoing {
    private static final String TAG = "AVDOutgoing";
    /** 获取AVDOutgoing接口对象
     *
     * @note AVDOutgoing是一个单例对象，一个进程空间只存在一个录制接口。
     * @return 返回AVDOutgoing。
     */
    public static AVDOutgoing instance() {
        return SingletonHolder.INSTANCE;
    }
    /**
     * 外呼设备接入回调接口类
     *
     * 外呼设备接入回调接口定义了引擎接口操作的异步返回。
     */
    public static interface Listener {
        /** 外呼用户创建操作异步返回
         *
         * @param[in] result 用户创建错误代码。
         * @param[in] roomId 房间Id。
         * @param[in] userId 用户Id。
         * @param[in] user_address 用户真实地址。
         *
         * @sa createOutgoingUser
         */
        public void onCreateOutgoingUser(int result, String roomId, String userid, String user_address);
        /** 外呼用户删除操作异步返回
         *
         * @param[in] result 用户删除错误代码。
         * @param[in] roomId 房间Id。
         * @param[in] userId 用户Id。
         * @param[in] user_address 用户真实地址。
         *
         * @sa destoryOutgoingUser
         */
        public void onDestoryOutgoingUser(int result, String roomId, String userid, String user_address);
        /** 外呼用户列表查询操作异步返回
         *
         * @param[in] result 用户列表查询错误代码。
         * @param[in] roomId 房间Id。
         *
         * @sa getOutgoingUsers
         */
        public void onGetOutgoingUsers(int result, String roomId, List<User> users);
    }

    ///
    private long nativeobj = 0;
    private long nativeListener = 0;
    private Listener listener4cb = null;
    private Handler listenerHandler = null;
    private SDKListener listener4native = null;
    ///
    private static class SingletonHolder {
        static final AVDOutgoing INSTANCE = new AVDOutgoing();
    }
    private AVDOutgoing() {
        nativeobj = nativegetAVDOutgoing();
        if (0 == nativeobj) {
            throw new RuntimeException("Failed to Create AVDOutgoing!");
        }
    }

    protected void initWithCB(Listener cb) {
        this.listener4cb = cb;
        if (0 == this.nativeListener) {
            initHandler();
            this.nativeListener = nativeCreateListener(listener4native);
            Tlog.d(TAG, "initWithCB, Create nativelistener:" + nativeListener);
        }
    }

    protected void dispose() {
        if (0 != this.nativeListener) {
            nativeFreeListener(this.nativeListener);
            this.nativeListener = 0;
        }
        this.listener4cb = null;
        this.listenerHandler = null;
        this.listener4native = null;
    }

    /** 设置房间聊天模块回调接口
     *
     * @param[in] listener 聊天模块回调接口指针。
     * @return 返回错误代码。
     * @sa Listener
     */
    public boolean setListener(Listener listener) {
        Tlog.d(TAG, "setListener, listener:" +listener+",listener4native="+this.listener4native+",listenerHandler="+this.listenerHandler);

        if (null == listener) {
            dispose();
        }
        else {
            initWithCB(listener);
        }
        Tlog.v(TAG, "setListener, out:");
        return true;
    }

    // 外呼接口
    /** 外呼用户创建
     *
     * @param[in] roomId 房间Id。
     * @param[in] user 用户信息，参考Room.join中对user的说明。
     * @param[in] user_address 用户真实地址，根据外呼用户的类型有区别：
     * 如rtsp为“rtsp://192.168.0.1:6549/avd”
     *	sip 为“sip://192.168.0.1:6549/avd"
     *	h323为“h323://192.168.0.1:6549/avd"
     * @param[in] loginName 用户真实地址的登陆名。
     * @param[in] loginPass 用户真实地址的登陆密码。
     * @param[in] assist_address 辅流取流地址，若有辅流，辅流也导入房间，房间中用户可以订阅主流或辅流。
     * @note 外呼用户创建为异步操作，调用此接口后等待回调中函数onCreateOutgoingUserResult回调，判断是否获取成功。
     *	   外呼用户包括： rtsp外呼；h323外呼；sip外呼等；
     * @return 返回错误代码。
     * @sa onCreateOutgoingUser
     */
    public int createOutgoingUser(String roomId, User user, String user_address, String loginName, String loginPass, String assist_address) {
        Tlog.i(TAG, "createOutgoingUser, roomId:" + roomId +",userid="+user.getUserId()
                +",user_address="+user_address +",loginName="+loginName+",assist="+assist_address);
        return nativecreateOutgoingUser(roomId,user,user_address,loginName,loginPass, assist_address);
    }
    /** 外呼用户删除
     *
     * @param[in] roomId 房间Id。
     * @param[in] userId 用户Id。
     * @param[in] user_address 用户真实地址。
     * @note外呼用户删除为异步操作，调用此接口后等待回调中函数onDestoryOutgoingUser回调，判断是否获取成功。
     * @return 返回错误代码。
     * @sa onDestoryOutgoingUser
     */
    public int destoryOutgoingUser(String roomId, String userid, String user_address) {
        Tlog.i(TAG, "destoryOutgoingUser, roomId:" + roomId +",userid="+userid+",user_address="+user_address);
        return nativedestoryOutgoingUser(roomId,userid, user_address);
    }
    /** 外呼用户列表查询
     *
     * @param[in] roomId 房间Id，此参数可为空，如果为空，返回整个服务器上的外呼用户列表；否则返回某一房间的外呼用户列表。
     * @note外呼用户列表查询为异步操作，调用此接口后等待回调中函数onGetOutgoingUsers回调，判断是否获取成功。
     * @return 返回错误代码。
     * @sa onGetOutgoingUsers
     */
    public int getOutgoingUsers(String roomId) {
        Tlog.i(TAG, "getOutgoingUsers, roomId:" + roomId );
        return nativegetOutgoingUsers(roomId);
    }

    ///
    private static native long nativegetAVDOutgoing();
    private native long nativeCreateListener(Listener listener);
    private native void nativeFreeListener(long nativeListener);
    private native int nativecreateOutgoingUser(String roomId, User user, String user_address,
                                                String loginName, String loginPass, String assist_address);
    private native int nativedestoryOutgoingUser(String roomId, String userid, String user_address);
    private native int nativegetOutgoingUsers(String roomId);
    ///
    private static final int msg_onCreateOutgoingUser = 1;
    private static final int msg_onDestoryOutgoingUser = 2;
    private static final int msg_onGetOutgoingUsers = 3;

    private boolean initHandler() {
        if (null == listener4native) {
            listener4native = new SDKListener();
        }
        if (null != listenerHandler) {
            return true;
        }
        AVDEngine.runOnLoopThreadSync(new Runnable() {
            @Override
            public void run() {
                initHandler_main();
            }
        });
        return true;
    }
    private boolean initHandler_main() {
        this.listenerHandler = new Handler(Looper.getMainLooper()) {
            public void handleMessage(Message msg) {
                Tlog.v(TAG, "handleMessage, msg:" + msg.toString());
            if (null == listener4cb) {
                super.handleMessage(msg);
                return;
            }
            switch (msg.what) {
                case msg_onCreateOutgoingUser:
                    listener4cb.onCreateOutgoingUser(
                            msg.getData().getInt("result"),msg.getData().getString("roomId"),msg.getData().getString("userId"),msg.getData().getString("userAddress"));
                    break;
                case msg_onDestoryOutgoingUser:
                    listener4cb.onDestoryOutgoingUser(
                            msg.getData().getInt("result"),msg.getData().getString("roomId"),msg.getData().getString("userId"),msg.getData().getString("userAddress"));
                    break;
                case msg_onGetOutgoingUsers:
                    listener4cb.onGetOutgoingUsers(msg.arg1,"", (List<User>) msg.obj);
                    break;
            }
            super.handleMessage(msg);
            }
        };
        return true;
    }
    private class SDKListener implements Listener {
        public SDKListener() {
        }
        public void onCreateOutgoingUser(int result, String roomId, String userid, String user_address) {
            if (null == listenerHandler) {
                return ;
            }
            Message msg = obtainMessage1(msg_onCreateOutgoingUser, result, roomId, userid, user_address);
            listenerHandler.sendMessage(msg);
        }
        @Override
        public void onDestoryOutgoingUser(int result, String roomId, String userid, String user_address) {
            if (null == listenerHandler) {
                return ;
            }
            Message msg = obtainMessage1(msg_onDestoryOutgoingUser, result, roomId, userid, user_address);
            listenerHandler.sendMessage(msg);
        }
        @Override
        public void onGetOutgoingUsers(int result, String roomId, List<User> users) {
            if (null == listenerHandler) {
                return ;
            }
            Message msg = Message.obtain(listenerHandler,msg_onGetOutgoingUsers,  result,0,users);
            listenerHandler.sendMessage(msg);
        }
    }
    private Message obtainMessage1(int what, int result, String roomId, String userId, String user_address) {
        Message msg = Message.obtain(listenerHandler);
        msg.what = what;
        Bundle data = new Bundle();
        data.putInt("result", result);
        data.putString("roomId", roomId);
        data.putString("userId", userId);
        data.putString("userAddress", user_address);
        msg.setData(data);
        return msg;
    }
}
