package cn.wise.sc.cement.business.util;

import cn.wise.sc.cement.business.model.Message;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/test-websocket/{sid}")
@Component
@Slf4j
public class WebSocketServer {
	/**
	 * 用于存放所有在线客户端
	 */
	private static Map<String, Session> clients = new ConcurrentHashMap<>();
//    private static Map<String, List<Message>> messages = new ConcurrentHashMap<>();

	/*@Value("${websocket.socketKey}")
	private String SOCKET_KEY;
	@Value("${websocket.host}")
	private String host;
	@Value("${websocket.port}")
	private int port;
	@Value("${websocket.timeout}")
	private int timeout;
	@Value("${websocket.clientDB}")
	private long clientDB;
	@Value("${websocket.selectDB}")
	private int selectDB;
	@Value("${websocket.password}")
	private String password;*/

	private static final String SOCKET_KEY = "socketkey";
	private static final String host = "localhost";
	private static final int port = 6379;
	private static final int timeout = 100000;
	private static final long clientDB = 2;
	private static final int selectDB = 2;
	private static final String password = "Wise_@123456";

	@OnOpen
	public void onOpen(Session session, @PathParam("sid") String sid) {
		log.info("有新的客户端上线: {}", session.getId());
		clients.put(sid, session);
		Jedis jedis = new Jedis(host, port, timeout);
//	    jedis.auth(password);
		jedis.select(selectDB);
//	    jedis.getClient().setDb(clientDB);
		List<Message> messageList = SerializeUtil.unserializeForList(jedis.get((SOCKET_KEY + sid).getBytes()));
		if (session != null) {
			for (int i = 0; i < messageList.size(); i++) {
				Message message = messageList.get(i);
				try {
					JSONObject json = (JSONObject) JSONObject.toJSON(message);
					String msg = json.toJSONString();
					session.getBasicRemote().sendText(msg);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			jedis.del((SOCKET_KEY + sid).getBytes());
		}
	}

	@OnClose
	public void onClose(Session session, @PathParam("sid") String sid) {
		String sessionId = session.getId();
		log.info("有客户端离线: {}", sessionId);
		clients.remove(sid);
	}

	@OnError
	public void onError(Session session, Throwable throwable, @PathParam("sid") String sid) {
		throwable.printStackTrace();
		if (clients.get(sid) != null) {
			clients.remove(sid);
		}
	}

	@OnMessage
	public void onMessage(String message) {
		log.info("收到客户端发来的消息: {}", message);
		this.sendTo(JSON.parseObject(message, Message.class));
	}

	/**
	 * 发送消息
	 *
	 * @param message 消息对象
	 */
	public void sendTo(Message message) {
		if (clients.get(message.getUserId()) == null) {
			Jedis jedis = new Jedis(host, port, timeout);
//	        jedis.auth(password);
			jedis.select(selectDB);
//	        jedis.getClient().setDb(clientDB);
			List<Message> messageList = SerializeUtil.unserializeForList(jedis.get((SOCKET_KEY + message.getUserId()).getBytes()));
			messageList.add(message);
			jedis.set((SOCKET_KEY + message.getUserId()).getBytes(), SerializeUtil.serialize(messageList));
		} else {
			Session s = clients.get(message.getUserId());
			if (s != null) {
				try {
					JSONObject json = (JSONObject) JSONObject.toJSON(message);
					String msg = json.toJSONString();
					s.getBasicRemote().sendText(msg);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
