package com.jeeplus.modules.sys.web;

import com.jeeplus.common.config.Global;
import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.common.utils.SmackUtils;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.chat2.Chat;
import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.sasl.provided.SASLPlainMechanism;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.search.ReportedData;
import org.jivesoftware.smackx.search.UserSearchManager;
import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * info:
 * Created by shang on 2017/8/1.
 */
@Controller
@RequestMapping(value = "${adminPath}/smack")
public class SmackController {
    protected String openfireServer = Global.getOpenfireServer();

    @RequestMapping("smackshow")
    @ResponseBody
    public Object index(String mobile, String body) {
        return sendSmackMessage(mobile, body);
    }

    @RequestMapping("smackshow2")
    @ResponseBody
    public Object smackshow2(String mobile, String body) {
        return SmackUtils.sendSmackMessage(mobile,body,"sys");
    }
    @RequestMapping("smackshow3")
    @ResponseBody
    public Object smackshow3(HttpServletRequest request) {
        String ip = getIpAddr(request);
        Map<String,Object> map = new HashMap<>();
        map.put("ip",ip);
        return map;
    }

    public AjaxJson sendSmackMessage(String mobile, String body) {
        AjaxJson ajaxJson = new AjaxJson();
        try {
            User user = UserUtils.get(mobile);
            if(user == null){
                user = UserUtils.getUser();
            }
            String message = "{\"msg\":\"审批信息 "+body+"\"," +
                    "\"fromPortrait\":\""+user.getPhoto()+"\"," +
                    "\"xmppChatType\":\"sys\","+
                    "\"fromUserName\":\"系统消息\","+
                    "\"bodyType\":\"txt\"}";
            if (StringUtils.isEmpty(mobile)) {
                ajaxJson.setSuccess(false);
            }
            AbstractXMPPConnection con = getXmpptcpConnection();
            con.connect();
            // 用户登录
            con.login();
            // 是否已经通过身份验证
            System.out.println("Authenticated = " + con.isAuthenticated());
            // Assume we've created an XMPPConnection name "connection"._
            ChatManager chatManager = ChatManager.getInstanceFor(con);
            chatManager.addIncomingListener(new IncomingChatMessageListener() {
                @Override
                public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
                    System.out.println("New message from " + from + ": " + message.getBody());
                }
            });
            EntityBareJid jid = JidCreate.entityBareFrom( mobile+"@"+openfireServer);//设置发送目标);
            Chat chat = chatManager.chatWith(jid);
            chat.send(message);
            /*if (con.isConnected()) {
                SASLAuthentication.registerSASLMechanism(new SASLPlainMechanism());
                con.loginAnonymously();//匿名登录
                UserSearchManager userSearchManager=new UserSearchManager(con);
                Form searchForm=userSearchManager.getSearchForm("search."+con.getServiceName());
                Form answerForm = searchForm.createAnswerForm();
                answerForm.setAnswer("Username", true);
                answerForm.setAnswer("search", mobile);
                ReportedData data=userSearchManager.getSearchResults(answerForm,"search."+con.getServiceName());
                List<ReportedData.Row> list = data.getRows();

                for (ReportedData.Row row : list) {
                    for (String jid : row.getValues("jid")) {
                        Message m = new Message();
                        m.setBody(body);//设置消息。
                        m.setTo(jid);//设置发送目标
                        if(deliveryReceiptRequest){
                            m.setType(Message.Type.normal);
                        }else{
                            m.setType(Message.Type.headline);
                        }
                        m.setSubject(body);
                        con.sendStanza(m);
                    }
                }
            }*/
            con.disconnect();
            ajaxJson.setSuccess(true);
            ajaxJson.setMsg("发送成功");
        } catch (Exception e) {
            System.out.println("Exception e:"+e);
            e.printStackTrace();
            ajaxJson.setSuccess(false);
            ajaxJson.setMsg("Exception e:"+e);
        }
        return ajaxJson;
    }

    private AbstractXMPPConnection getXmpptcpConnection() throws XmppStringprepException {
        XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
        configBuilder.setUsernameAndPassword("1@"+openfireServer, "admin");
        configBuilder.setResource("sys");
        configBuilder.setXmppDomain(openfireServer);
        configBuilder.setHost(openfireServer);
        configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
       /* config.setServiceName(openfireServer);
        config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        config.setSendPresence(true);
        config.setCompressionEnabled(false);
        config.setPort(5288);*/
        //config.setUsernameAndPassword("1@oa-pre.ssruihua.com", "admin");
        AbstractXMPPConnection connection = new XMPPTCPConnection(configBuilder.build());
        /*SASLAuthentication.blacklistSASLMechanism("SCRAM-SHA-1");
        SASLAuthentication.blacklistSASLMechanism("DIGEST-MD5");
        SASLAuthentication.blacklistSASLMechanism("CRAM-MD5");*/
        return connection;
    }


    /**
     * 获取用户真实IP地址，不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值
     *
     * @return ip
     */
    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        System.out.println("x-forwarded-for ip: " + ip);
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if( ip.indexOf(",")!=-1 ){
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
            System.out.println("Proxy-Client-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
            System.out.println("WL-Proxy-Client-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
            System.out.println("HTTP_CLIENT_IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
            System.out.println("X-Real-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            System.out.println("getRemoteAddr ip: " + ip);
        }
        System.out.println("获取客户端ip: " + ip);
        return ip;
    }
}
