
var translate = require("./translate");

var proxy_message = require("./proxy_message");
var tool = require("./tool");
var net =require("net");
exports.ProxyClient = ProxyClient;
var version = require("./version")

function ProxyClient(addrlist){
	this.addr_list_ = addrlist;
	this.cur_addr_ = this.addr_list_[0];
	this.index_ = 0;
}
ProxyClient.prototype._SendWaitMessge = function(smsg,cb){
	var obj = tool.ParseAddr(this.cur_addr_);
	if(!obj){
		return false;
	}
	var self = this;
	var timer = setTimeout(function(){
		cb(null,"timeout");
		self.NextAddr();
	},10000)
	var cli = new translate.TcpClient();
	cli.Connect(obj.ip,obj.port);
	cli.on("openfail",function(err){
		clearTimeout(timer);
		self.NextAddr();
		cb(null,"connect.fail.err="+err+"addr:"+self.cur_addr_);
	})
	cli.on("message",function(msg){
		clearTimeout(timer);
		cb(msg,null);
		cli.Close();
	})
	cli.on("close",function(err){
		clearTimeout(timer);
		self.NextAddr();
		cb(null,"connect.fail.close="+err+"addr:"+self.cur_addr_);
	})
	cli.Send(smsg);
}
ProxyClient.prototype.GetMaster = function(appid,num,cb){
	var msg = new proxy_message.MProxyGetMaster(appid,version.APP_VERSION,num);
	this._SendWaitMessge(msg,function(back,err){
		if(err){
			cb(err);
		}else{
			if(back.code != 0){return cb(back.err);}
			var obj = tool.ParseAddr(back.addr);
			var inobj = tool.ParseAddr(back.inaddr);
			_Ping([inobj],function(err,addr){
				if(err){
					cb(null,obj);
				}else{
					cb(null,inobj);
				}
			})
		}
	})
}

ProxyClient.prototype.GetGate = function(appid,cb){
	var req = new proxy_message.MProxyGetGate(appid);
	this._SendWaitMessge(req,function(back,err){
		if(err){
			cb(err);
		}else{
			var arr = [];
			if(back.code != 0){
				cb(back.err,null);
				return;
			}
			for(var i in back.addrs){
				var obj = tool.ParseAddr(back.addrs[i]);
				if(obj)arr.unshift(obj);
			}
			_Ping(arr,cb);
		}
	});
}
function _Ping(addrlist,cb){
	if(addrlist.length == 0){
		cb("no free gate",null);
		return;
	}
	var socketarr = [];
	var num = addrlist.length;
	function destroy(){
		for(var i in socketarr){
			socketarr[i].destroy();
			socketarr[i].removeAllListeners();
		}
	}
	for(var i in addrlist){
		var socket = Connect(addrlist[i],function(err,addr){
			if(err){
				if(--num == 0){
					destroy();
					cb("no addr ok",null);
				}
			}else{
				destroy();
				cb(null,addr);
			}
		});
		socketarr.push(socket);
	}
}
function Connect(addr,cb){
	var socket = new net.Socket();
	var self = this;
	var timer = setTimeout(function(){
		cb("timeout",null);
		socket.destroy();
	},3000)
	socket.on("error",function(err){
		clearTimeout(timer);
		cb(err,null);
	})
	socket.on("connect",function(){
		clearTimeout(timer);
		cb(null,addr);
	})
	socket.connect(addr.port,addr.ip);
	return socket;
}
ProxyClient.prototype._Send = function(msg){
	return this.client_pool_.SendToAddr(msg,this.cur_addr_);
}

ProxyClient.prototype.NextAddr = function(){
	this.index_ = (this.index_+1)%this.addr_list_.length;
	this.cur_addr_ = this.addr_list_[this.index_];
}
ProxyClient.prototype._OnClose = function(addr){
	this.NextAddr();
	this.rpc_client_.OnClose();
}
ProxyClient.prototype._OnMessage = function(addr,msg){
	this.rpc_client_.OnMsg(msg);
}
