//引入http模块
var socketio = require('socket.io'),
	fs 	= require('fs'),
	https     = require('http'),
	domain   = require('domain'),
	redis    = require('redis'),
    redisio  = require('socket.io-redis'),
    request  = require('request'),
    md5  = require('md5-node'),
    config   = require('./config.js');

var d = domain.create();
d.on("error", function(err) {
	//console.log(err);
});

var sockets = {};
var chat_history={};
var chat_interval={};
/* 主播连麦关系 */
var LiveConnect={};
var LiveConnect_pull={};

// redis 链接
var clientRedis  = redis.createClient(config['REDISPORT'],config['REDISHOST']);
// clientRedis.auth(config['REDISPASS']);
//var server = https.createServer(options,function(req, res) {
var server = https.createServer(function(req, res) {
	res.writeHead(200, {
		'Content-type': 'text/html;charset=utf-8'
	});
    
   //res.write("人数: " + numscount );
	res.end();
}).listen(config['socket_port'], function() {
	////console.log('服务开启19965');
});

var field=[];

var io = socketio.listen(server,{
	pingTimeout: 60000,
  	pingInterval: 25000
});



io.on('connection', function(socket) {
    //console.log(FormatNowDate());
	//console.log('连接成功');
	//numscount++;
							
	var interval;

    /* 获取服务端配置 */
    request(config['WEBADDRESS']+"?service=Home.getFilterField",function(error, response, body){
        if(error){
            //console.log(error);
            return;
        } ;
        if(!body){
            //console.log(body);
            return;
        } ;
        var res = evalJson(body);
        //console.log(body);
        //console.log(res.data.info);
        //console.log("sssss");
        field = res.data.info;
    });

	//进入房间
	socket.on('conn', function(data) {
		// console.log('data');
		// console.log(data);
		if(!data || !data.token){
				return !1;
		}
		
		userid=data.uid;

        if(userid<0 && userid==-9999){ //app端
            userid=data.mobileid;
            data.uid=data.mobileid;
            data.token=data.mobileid;
        }

		old_socket = sockets[userid];
		if (old_socket && old_socket != socket) {
			
			if(data.uid != data.roomnum && data.uid==old_socket.roomnum){
                /* 进房间 但旧链接是 主播 */
                var data_str='{"retmsg":"ok","retcode":"000000","msg":[{"msgtype":"1","_method_":"StartEndLive","action":"19","ct":"直播关闭"}]}';
				old_socket.emit('broadcastingListen',[data_str]);
			}else if(data.uid== data.roomnum && data.stream==old_socket.stream){
                /* 主播重连 */
				old_socket.reusing = 1;
				//console.log("重用");
			}else if(data.uid== data.roomnum && data.stream!=old_socket.stream){
                /* 主播多端开播 */
				var data_str='{"retmsg":"ok","retcode":"000000","msg":[{"msgtype":"1","_method_":"StartEndLive","action":"19","ct":"直播关闭"}]}';
				old_socket.emit('broadcastingListen',[data_str]);
			}
			old_socket.disconnect()
		}
		
		clientRedis.get(data.token,function(error,res){
            
			if(error){
				return;
			}else if(res==null){
				console.log("[获取token失败]"+data.uid);
			}else{
				if(res != null){
					
					var userInfo = evalJson(res);
					//console.log("用户进入直播间-----------"+res); 
					if(userInfo['id'] == data.uid ){
						//console.log("[初始化验证成功]--"+data.uid+"---"+data.roomnum+'---'+data.stream);
						//获取验证token
						socket.token   = data.token; 
						socket.roomnum = data.roomnum;
						socket.stream = data.stream;
						socket.nicename = userInfo['user_nicename'];
						socket.level = userInfo['level'];
						socket.avatar = userInfo['avatar'];
						socket.sign = Number(userInfo['sign']);
						socket.usertype   = parseInt(userInfo['usertype']);
						socket.uid     = data.uid;
						socket.reusing = 0;
						
						socket.join(data.roomnum);
						sockets[userid] = socket;
						socket.emit('conn',['ok']);
                        
						if( socket.roomnum!=socket.uid && socket.uid >0 ){
                            
							var data_obj={
                                            "msg":[
                                                {
                                                    "_method_":"SendMsg",
                                                    "action":"0",
                                                    "ct":{
                                                        "id":''+userInfo['id'],
                                                        "user_nicename":''+userInfo['user_nicename'],
                                                        "avatar":userInfo['avatar'],
                                                        "avatar_thumb":userInfo['avatar_thumb'],
                                                        "level":''+userInfo['level'],
                                                        "usertype":''+userInfo['usertype'],
                                                    },
                                                    "msgtype":"0"
                                                }
                                            ],
                                            "retcode":"000000",
                                            "retmsg":"OK"
                                        };
							console.log(userInfo['usertype']);
							process_msg(io,socket.roomnum,JSON.stringify(data_obj));
							if(socket.stream){
								clientRedis.zadd('user_'+socket.stream,socket.sign,userInfo['id']);	
							}
						}						
						 
						// sendSystemMsg(socket,"直播内容包含任何低俗、暴露和涉黄内容,账号会被封禁;安全部门会24小时巡查哦~");
                        sendSystemMsg(socket,"欢迎来到直播间,我们倡导绿色直播。直播内容和封面有违法违规、色情低俗、抽烟喝酒、诱导欺诈、聚众闹事等行为账号会被封禁,网警24小时在线巡查哦!");
						return;
					}else{
						socket.disconnect();
					}
				}
			}
			
			socket.emit('conn',['no']);
		});
        
		
	});

	socket.on('broadcast',function(data){
            //console.log(data);
		    if(socket.token != undefined){
		    	var dataObj  = typeof data == 'object'?data:evalJson(data);
			    var msg      = dataObj['msg'][0]; 
			    var token    = dataObj['token'];
				var method   = msg['_method_'];
			    var action   = msg['action'];
			    var data_str =  typeof data == 'object'?JSON.stringify(data):data;
			    switch(method){
			    	case 'SendMsg':{     //聊天

                        dataObj['msg'][0]['ct']=filter(dataObj['msg'][0]['ct']);
						clientRedis.hget( "super",socket.uid,function(error,res){
							if(error) return;
							if(res != null){
								var data_str2={
                                                "msg":[
                                                    {
                                                        "_method_":"SystemNot",
                                                        "action":"1",
                                                        "ct":''+dataObj['msg'][0]['ct'],
                                                        "msgtype":"4"
                                                    }
                                                ],
                                                "retcode":"000000",
                                                "retmsg":"OK"
                                            };
								process_msg(io,socket.roomnum,JSON.stringify(data_str2));
		    				}else{

                                data_str=JSON.stringify(dataObj);

								clientRedis.hget(socket.roomnum + "shutup",socket.uid,function(error,res){
									if(error) return;
									if(res != null){
                                        var newData  = dataObj;
                                        newData['retcode'] = '409002';
                                        socket.emit('broadcastingListen',[JSON.stringify(newData)]);
									}else{
										process_msg(io,socket.roomnum,data_str);
									}	
								});
		    				}							
						});
			    		break;
			    	}
			    	case 'SendGift':{    //送礼物
						var gifToken = dataObj['msg'][0]['ct'];
						console.log('送礼物gifToken');
						console.log(gifToken);
			    		clientRedis.get(gifToken,function(error,res){
							console.log('get送礼物');
							console.log(error);
							console.log(res);
			    			if(!error&&res != null){
			    				
                                var sendGiftObj = evalJson(res);

                                console.log(sendGiftObj);

                                var len=sendGiftObj.length;

                                for (var i = 0; i < len; i++) {
                                    var  resObj= sendGiftObj[i];

                                    dataObj['msg'][0]['ct'] = resObj;
                    
                        
                                    io.sockets.in(socket.roomnum).emit('broadcastingListen',[JSON.stringify(dataObj)]);
                             

                                }

			    				
                                
			    				clientRedis.del(gifToken);
			    			}
			    		});
			    		break;
			    	}
					case 'SendBarrage':{    //弹幕
						var barragetoken = dataObj['msg'][0]['ct'];
			    		clientRedis.get(barragetoken,function(error,res){
			    			if(!error&&res != null){
			    				var resObj = evalJson(res);

                                var con=resObj.content;
                                var res = filter(con);
                                resObj.content=res;

			    				dataObj['msg'][0]['ct'] = resObj;
								var data_str=JSON.stringify(dataObj);
								process_msg(io,socket.roomnum,data_str);
			    				clientRedis.del(barragetoken);
			    			}	
			    		});
			    		break;
			    	}
					
					case 'light' :{     //点亮
						process_msg(io,socket.roomnum,data_str);
	                    break;
			    	}
	
					case 'updateVotes' :{//更新映票
						process_msg(io,socket.roomnum,data_str);
	                    break;
			    	}


			    	case 'StartEndLive':{
			    		if(socket.usertype == 50 ){
			    		   socket.broadcast.to(socket.roomnum).emit('broadcastingListen',[data_str]);
			    	    }else{
			    	    	clientRedis.get("LiveAuthority" + socket.uid,function(error,res){
			    	    		if(error) return;
			    	    		if(parseInt(res) == 5 ||parseInt(res) == 1 || parseInt(res) == 2){
		    	    				socket.broadcast.to(socket.roomnum).emit('broadcastingListen',[data_str]);
		    	    			}
			    	    	})
			    	    }
			    	    break;

			    	}
		
                  
                
			    	case 'SystemNot':{//系统通知
						process_msg(io,socket.roomnum,data_str);
			    		break;
			    	}
              

	
						
			    }
		    }
		    
	});
	
	socket.on('superadminaction',function(data){
    	if(data['token'] == config['TOKEN']){
            io.sockets.in(data['roomnum']).emit("broadcastingListen", ['stopplay']);
    	}
    });
	/* 系统信息 */
	socket.on('systemadmin',function(data){
    	if(data['token'] == config['TOKEN']){
            var data_obj={
                            "msg":[
                                {
                                    "_method_":"SystemNot",
                                    "action":"1",
                                    "ct":''+ data.content,
                                    "msgtype":"4"
                                }
                            ],
                            "retcode":"000000",
                            "retmsg":"OK"
                        };
    		io.emit('broadcastingListen',[JSON.stringify(data_obj)]);
    	}
    });
	
    //资源释放
	socket.on('disconnect', function() { 
        // console.log(FormatNowDate());
        // console.log('disconnect');

          			
			if(socket.roomnum ==null || socket.token==null || socket.uid <=0){
				return !1;
			}
				
			d.run(function() {

				
				
				if(socket.roomnum==socket.uid){
					/* 主播 */ 
					if(socket.reusing==0){
						request(config['WEBADDRESS']+"?service=Live.stopRoom&uid="+socket.uid + "&token=" + socket.token+ "&type=1&source=socket&stream=" + socket.stream,function(error, response, body){
                            var data_obj={
                                        "retmsg":"ok",
                                        "retcode":"000000",
                                        "msg":[
                                            {
                                                "msgtype":"1",
                                                "_method_":"StartEndLive",
                                                "action":"18",
                                                "ct":"直播关闭"
                                            }
                                        ]
                                    };
                            process_msg(io,socket.roomnum,JSON.stringify(data_obj));
                            // console.log('关播');
                            // console.log(FormatNowDate());
                            // console.log('uid---'+socket.uid);
                        });
                        endLiveConnect(io,socket.uid);
					}
                    
                    
                    
				}else{

					/* 观众 */
                    clientRedis.zrem('user_'+socket.stream,socket.uid,function(error,res){
						if(error) return;
						if(res){

							var data_obj={
                                            "msg":[
                                                {
                                                    "_method_":"disconnect",
                                                    "action":"1",
                                                    "ct":{
                                                        "id":''+socket.uid,
                                                        "user_nicename":''+socket.nicename,
                                                        "avatar":socket.avatar,
                                                        "level":''+socket.level
                                                    },
                                                    "msgtype":"0",
                                                    "uid":''+socket.uid,
                                                    "uname":socket.nicename
                                                }
                                            ],
                                            "retcode":"000000",
                                            "retmsg":"OK"
                                        };
							process_msg(io,socket.roomnum,JSON.stringify(data_obj));	
						}
						
					});

                    clientRedis.del(socket.token);
                    clientRedis.hdel('super',socket.uid);


					
				}
				////console.log(socket.roomnum+"==="+socket.token+"===="+socket.uid+"======"+socket.stream);
				
				socket.leave(socket.roomnum);
				delete io.sockets.sockets[socket.id];
				sockets[socket.uid] = null;
				delete sockets[socket.uid];

			});
	});

});
function sendSystemMsg(socket,msg){
    var data_obj={
                    "msg":[
                        {
                            "_method_":"SystemNot",
                            "action":"1",
                            "ct":""+ msg,
                            "msgtype":"4"
                        }
                    ],
                    "retcode":"000000",
                    "retmsg":"OK"
                };
	socket.emit('broadcastingListen',[JSON.stringify(data_obj)]);
						
}
function evalJson(data){
	return eval("("+data+")");
}

function process_msg(io,roomnum,data){
	if(!chat_history[roomnum]){
		chat_history[roomnum]=[];
	}
	chat_history[roomnum].push(data);
	chat_interval[roomnum] || (chat_interval[roomnum]=setInterval(function(){
		if(chat_history[roomnum].length>0){
			send_msg(io,roomnum);
		}else{
			clearInterval(chat_interval[roomnum]);
			chat_interval[roomnum]=null;
		}
	},200));
}

function send_msg(io,roomnum){
	var data=chat_history[roomnum].splice(0,chat_history[roomnum].length);
    io.sockets.in(roomnum).emit("broadcastingListen", data);
}


//时间格式化
function FormatNowDate(){
	var mDate = new Date();
	var Y = mDate.getFullYear();
	var M = mDate.getMonth()+1;
	var D = mDate.getDate();
	var H = mDate.getHours();
	var i = mDate.getMinutes();
	var s = mDate.getSeconds();
	return Y +'-' + M + '-' + D + ' ' + H + ':' + i + ':' + s;
}

/* sign加密 */
function setSign(obj) {//排序的函数
    var str='';
    var newkey = Object.keys(obj).sort();
//先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
    var newObj = {};//创建一个新的对象,用于存放排好序的键值对
    for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
        //newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
        str+=newkey[i]+'='+obj[newkey[i]]+'&';
    }
    str+=config['sign_key'];
    
    var sign=md5(str);
    return sign;
}

//过滤函数
function filter(str) {

  // 多个敏感词,这里直接以数组的形式展示出来
  var arrMg = field;
  //console.log(arrMg);
  // 显示的内容--showContent
  var showContent = str;
//console.log(showContent);
  // 正则表达式
  // \d 匹配数字
  for (var i = 0; i < arrMg.length; i++) {
    // 创建一个正则表达式
    var r = new RegExp(arrMg[i], "ig");
    var re='';
    for(var n=0;n<arrMg[i].length;n++){
        re+='*';
    }
    showContent = showContent.replace(r, re);
  }
  // 显示的内容--showInput
    //console.log(showContent);
    return showContent;

}