
var net = require('net');
var coder = require("../coder");
var translate = require("../translate");
var rpc_msg = require("./rpc_message");


var util = require("util");
var events = require("events");


exports.RpcServer = RpcServer;

function RpcServer (){
	events.EventEmitter.call(this);
	this.func_map_ = {};
	this.server_ = null;
}
util.inherits(RpcServer, events.EventEmitter);
RpcServer.prototype.Start = function(port){
	var self = this;
	this.server_ = net.createServer(function(c) { //'connection' listener
	 	self._OnClient(c);
	});
	if(port){
		this.server_.listen(port, function() { //'listening' listener
		  self.emit("open");
		});	
	}else{
		this.server_.listen( function() { //'listening' listener
		  self.emit("open");
		});	
	}
	
	this.server_.on('error', function (e) {
		console.log("error",e);
	 	self.emit("close",e);
	});
}
RpcServer.prototype.Stop = function(){
	if(this.server_){
		this.server_.removeAllListeners();
		this.server_.close();
		this.server_ = null;	
	}
}
RpcServer.prototype.GetAddr = function(){
	return this.server_.address();
}
RpcServer.prototype._OnClient = function(socket){
	var self = this;
	var conn = new translate.TcpConn(socket);
	conn.on("message",function(msg){
		self._OnMessage(conn,msg);
	})
	conn.on("close",function(err){
		
	})
}
function CallBack(conn,seq){
	this.rsp_ = new rpc_msg.RpcResponce(seq);
	this.conn_ = conn;
}
CallBack.prototype.Flush = function(type){
	if(!this.conn_) return;
	this.rsp_.SetType(type);
	this.conn_.Send(this.rsp_);
	this.conn_ = null;
}
RpcServer.prototype._OnMessage = function(conn,msg){
	var tag = msg.GetTag();
	if(tag == coder.TAG.ADCLOUD_MESSAGE_TAG_RPC_REQ){
		var fn = this.func_map_[msg.methodname_];
		if(fn){
			var callback = new CallBack(conn,msg.seq_);
			fn(msg.GetType(),callback.Flush.bind(callback));
		}else{
			var rsp = new rpc_msg.RpcResponce(msg.seq_,new coder.TypeError("no method"));
			conn.Send(rsp);
		}
	}else{
		conn.Close();
	}
}
RpcServer.prototype.RegistFunction = function(name,func){
	this.func_map_[name] = func;
}