package com.saki.client;

import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.saki.QVMProtect;
import com.saki.http.Http;
import com.saki.encode.Canvart;
import com.saki.encode.Code;
import com.saki.log.Log;
import com.saki.log.SQLog;
import com.saki.qq.global.Key;
import com.saki.qq.global.MsgManager;
import com.saki.qq.global.Token;
import com.saki.qq.global.TroopManager;
import com.saki.qq.wtlogin.pack.send.GrayUinPro;
import com.saki.qq.wtlogin.pack.send.MessageSvc;
import com.saki.qq.wtlogin.pack.send.OidbSvc;
import com.saki.qq.wtlogin.pack.send.OnlinePush;
import com.saki.qq.wtlogin.pack.send.ProfileService;
import com.saki.qq.wtlogin.pack.send.StatSvc;
import com.saki.qq.wtlogin.unpack.QQUnPacket;
import com.saki.qq.wtlogin.unpack.ReConfigPushSvc;
import com.saki.qq.wtlogin.unpack.ReFriendList;
import com.saki.qq.wtlogin.unpack.ReGrayUinPro;
import com.saki.qq.wtlogin.unpack.ReMessageSvc;
import com.saki.qq.wtlogin.unpack.ReOidSvc;
import com.saki.qq.wtlogin.unpack.ReServer;
import com.saki.qq.wtlogin.unpack.ReUnHandled;
import com.saki.qq.wtlogin.unpack.ReFriendList.GetTroopMemberList;
import com.saki.qq.wtlogin.unpack.ReMessageSvc.PbGetMsg;
import com.saki.qq.wtlogin.unpack.ReMessageSvc.PbGetMsg.Msg;
import com.saki.qq.wtlogin.unpack.ReOnlinePush.PbPushDisMsg;
import com.saki.qq.wtlogin.unpack.ReOnlinePush.PbPushGroupMsg;
import com.saki.qq.wtlogin.unpack.ReOnlinePush.PbPushTransMsg;
import com.saki.qq.wtlogin.unpack.ReOnlinePush.ReqPush;
import com.saki.qq.wtlogin.unpack.ReProfileService.Pb.ReqSystemMsgNew.Group;
import com.saki.qq.wtlogin.unpack.ReProfileService.Pb.ReqSystemMsgNew.Group.SysMsg;
import com.saki.qq.wtlogin.unpack.RecviePack;
import com.saki.qq.wtlogin.unpack.UnknownPacketException;
import com.saki.service.IOData;
import com.saki.service.IOData.Data;
import com.saki.service.NewService;
import com.saki.service.SimpleGetThread;
import com.saki.service.SocketClient;
import com.saki.tools.FileUtil;
import com.saki.ui.NewLoginActivity;
import com.saki.ui.listener.IMessageListener;
import com.saki.ui.listener.ITroopListener;
@QVMProtect
public class Client implements IClient {
    @QVMProtect
    public class SQ extends SocketClient {
        private SimpleGetThread simlpeGet;

        public SQ() throws UnknownHostException, IOException {
            super("msfwifi.3g.qq.com", 8080);
        }

        @Override
        public void error(IOException e) {
            super.error(e);
            simlpeGet.destroy();
            reConnect();
        }

        @Override
        public void doReceive(byte[] byteArray) {
            RecviePack pack;
            try {
                pack = QQUnPacket.unPacket(byteArray);
                // 未处理的数据包
                if (pack instanceof ReUnHandled) {
                    Log.i(this, "read unHandler");
                    Log.i(this, Canvart.Bytes2Hex(pack.getData()));
                    return;
                }
                // 服务器数据包
                if (pack instanceof ReServer) {
                    doServerReturn(post2Server(pack.getData()));
                    return;
                }
                // 离线数据包
                if (pack instanceof ReMessageSvc.PushForceOffline) {
                    destroy();
                } else
                // 其他消息数据包，好友消息，临时消息，系统消息
                if (pack instanceof PbGetMsg) {
                    // 其他消息
                    for (Msg m : ((PbGetMsg) pack).msgList) {
                        if (m.type == PbGetMsg.T_SYS_UNREAD
                                || m.type == PbGetMsg.T_JOIN_GRUP
                                || m.type == PbGetMsg.T_SYS_INVIT)
                            send(new ProfileService.Pb.ReqSystemMsgNew.Group(
                                    getRequstionID()).toByteArray());
                    }
                    iMessage.onOtherMsg((PbGetMsg) pack);
                } else
                // 新的系统消息
                if (pack instanceof Group) {
                    Log.i(this, "系统消息");
                    Group g = (Group) pack;
                    send(new ProfileService.Pb.ReqSystemMsgRead.Group(
                            getRequstionID(), g.requstId).toByteArray());
                    for (SysMsg m : g.list) {
                        Log.i(this, m.toString());
                        if (m.type == Group.UNREAD) {
                            iMessage.onSystemMsg(m);
                        }
                    }
                } else
                // 消息推送
                if (pack instanceof ReMessageSvc.PbshNotify) {
                    send(new MessageSvc.PbGetMsg(getRequstionID())
                            .toByteArray());
                } else
                // if(pack instanceof ReStatSvc.Register){
                // send(new MessageSvc.PbGetMsg(getRequstionID()));
                // }else
                // 主推送
                if (pack instanceof /* ReStatSvc.Register){// */ ReConfigPushSvc.PushDomain) {
                    if (simlpeGet == null) {
                        simlpeGet = new SimpleGetThread(Client.this);
                        pool.execute(simlpeGet);
                    }
                    service.updataUI(NewLoginActivity.CMD_LOGIN_SUCCESS, null);
                } else
                // 状态变化消息
                if (pack instanceof PbPushTransMsg) {
                    PbPushTransMsg m = (PbPushTransMsg) pack;
                    send(new OnlinePush.RespPush(getRequstionID(), m.requstId,
                            null).toByteArray());
                    iMessage.onTransMsg((PbPushTransMsg) pack);
                } else
                // 消息推送
                if (pack instanceof ReqPush) {
                    ReqPush p = (ReqPush) pack;
                    send(new OnlinePush.RespPush(getRequstionID(), p.requstid,
                            p.listPack.list).toByteArray());
                } else
                // 讨论组消息
                if (pack instanceof PbPushDisMsg) {

                    send(new OnlinePush.RespPush(getRequstionID(),
                            pack.info.seq, null).toByteArray());
                    iMessage.onDisMsg((PbPushDisMsg) pack);
                } else
                // 群消息
                if (pack instanceof PbPushGroupMsg) {
                    iMessage.onGroupMsg((PbPushGroupMsg) pack);
                } else
                // 获取群列表
                if (pack instanceof ReFriendList.GetTroopListReqV2) {
                    iTroop.onTroop(((ReFriendList.GetTroopListReqV2) pack).list.list);
                } else
                // 获取好友列表
                if (pack instanceof ReFriendList.GetFriendGroupList) {

                } else
                // 获取群成员列表
                if (pack instanceof GetTroopMemberList) {
                    GetTroopMemberList members = (GetTroopMemberList) pack;
                    iTroop.onTroopMember(members.list.groupid,
                            members.list.list);
                } else if (pack instanceof ReOidSvc.Ox59f) {
                    send(new OidbSvc.Ox496(getRequstionID()).toByteArray());
                } else if (pack instanceof ReOidSvc.Ox496) {
                    send(new OidbSvc.Ox7c4_0(getRequstionID()).toByteArray());
                } else if (pack instanceof ReOidSvc.Ox7c4_0) {
                    send(new OidbSvc.Ox7a2_0(getRequstionID()).toByteArray());
                } else if (pack instanceof ReOidSvc.Ox7a2_0) {
                    send(new StatSvc.Register(getRequstionID()).toByteArray());
                } else if (pack instanceof ReGrayUinPro) {
                    Key.changeKey(Key.KSESSION);
                    send(new OidbSvc.Ox59f(getRequstionID()).toByteArray());
                }
            } catch (UnknownPacketException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }

        }

    }

    public static final String BASE_URL = "http://setqqv8.top:8080/SQv8/Server";
    private IMessageListener iMessage = MsgManager.getInstance();
    private ITroopListener iTroop = TroopManager.getInstance();
    private ExecutorService pool = Executors.newCachedThreadPool();
    private int seq;
    private SocketClient socket;
    private NewService service;
    Http h = new Http();

    public Client(NewService service) {
        this.service = service;
        pool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new SQ();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public void releseSocket(){
        this.socket.destroy();
    }
    public void doServerReturn(byte[] bin) {
        if (bin == null || bin.length == 0) {
            service.updataUI(NewLoginActivity.CMD_LOGIN_FAILT, "服务器解包失败");
            return;
        }
        // 创建解析类
        IOData data = new IOData(bin);
        Data d = null;
        // 遍历结果
        while ((d = data.next()) != null) {
            if (d.type == IOData.VERIFFYCODE) {
                // 需要验证码
                service.updataUI(NewLoginActivity.CMD_VERIFYCODE, d.data);
            } else if (d.type == IOData.ERROR) {
                // 错误消息
                service.updataUI(NewLoginActivity.CMD_LOGIN_FAILT,new String(d.data).replaceAll("[^\u0020-\u9FA5]",""));
            } else if (d.type == IOData.TOKEN) {
                if (d.data.length == 0x40) {
                    Token.T0044 = d.data;
                } else if (d.data.length == 0x48) {
                    Token.T004C = d.data;
                }
            } else if (d.type == IOData.SEQ) {
                seq = Canvart.Bytes2Int(d.data);
            } else if (d.type == IOData.KEY) {
                Key.KSESSION = d.data;
            } else if (d.type == IOData.PACK) {
                send(d.data);
            }else if(d.type == IOData.MSG){
                service.updataUI(NewLoginActivity.CMD_OTHER,new String(d.data));
            }
        }
    }
    @QVMProtect
    public void reConnect(){
        try {
            this.socket = new SQ();
            Key.changeKey(Key.KDEFAULT);
            send(new GrayUinPro.Check(getRequstionID()).toByteArray());
            SQLog.i("网络已重新连接");
        } catch (IOException e) {
            e.printStackTrace();
            SQLog.e("重连失败30s后重试:"+e.toString());
            try {
                Thread.sleep(30000);
                reConnect();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    }

    @Override
    public int getRequstionID() {
        return seq++;
    }

    public void login(final String id, final String password,final int version) {
        pool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    String path = service.getPackageCodePath();
                    byte[] bin = FileUtil.readFile(new File(path));
                    byte[] key = Code.MD5(bin);
                    byte[] psdData = Code.QQTEAencrypt(password.getBytes(),key);
                    bin = h.call("GET",BASE_URL + "?ver="+version+"&id=" + id + "&password="
                            + Canvart.Bytes2Hex(psdData,""),null);
                    doServerReturn(bin);
                } catch (Exception e) {
                    service.updataUI(NewLoginActivity.CMD_LOGIN_FAILT,"网络异常");
                }
            }
        });
    }

    private byte[] post2Server(byte[] bin) {
        try {
            return h.call("POST",BASE_URL, bin);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void send(final byte[] bin) {
        pool.execute(new Runnable() {
            @Override
            public void run() {
                socket.send(bin);
            }
        });
    }

    public void verifyCode(final String vc) {
        pool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    byte[] bin = h.call("GET",BASE_URL + "?verifycode=" + vc,null);
                    doServerReturn(bin);
                } catch (Exception e) {
                    service.updataUI(NewLoginActivity.CMD_LOGIN_FAILT,"网络异常");
                }
            }
        });
    }
}
