package org.craft.atom.rpc;

import java.lang.reflect.Method;

import lombok.Getter;
import lombok.Setter;

import org.craft.atom.protocol.rpc.model.RpcMethod;
import org.craft.atom.protocol.rpc.model.RpcOption;
import org.craft.atom.rpc.api.RpcServer;
import org.craft.atom.rpc.spi.RpcAcceptor;
import org.craft.atom.rpc.spi.RpcInvoker;
import org.craft.atom.rpc.spi.RpcProcessor;
import org.craft.atom.rpc.spi.RpcProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author mindwind
 * @version 1.0, Aug 6, 2014
 */
public class DefaultRpcServer implements RpcServer {
	
	
	private static final Logger LOG = LoggerFactory.getLogger(DefaultRpcServer.class);
	
	
	@Getter @Setter private String               host             ;
	@Getter @Setter private int                  port             ;
	@Getter @Setter private int                  ioTimeoutInMillis;
	@Getter @Setter private RpcAcceptor          acceptor         ;
	@Getter @Setter private RpcProcessor         processor        ;
	@Getter @Setter private RpcProtocol          protocol         ;
	@Getter @Setter private RpcInvoker           invoker          ;
	@Getter @Setter private RpcRegistry          registry         ;

	
	// ~ -------------------------------------------------------------------------------------------------------------
	
	
	public DefaultRpcServer() {
		ioTimeoutInMillis = 5 * 60 * 1000;
		invoker   = new DefaultRpcInvoker();
		protocol  = new DefaultRpcProtocol();
		processor = new DefaultRpcProcessor();
		acceptor  = new DefaultRpcAcceptor();
		registry  = RpcRegistry.getInstance();
		acceptor .setProcessor(processor);
		acceptor .setProtocol(protocol);
		processor.setInvoker(invoker);
	}
	
	
	// ~ -------------------------------------------------------------------------------------------------------------
	
	
	@Override
	public void serve() {
		try {
			acceptor.bind(host, port, ioTimeoutInMillis);
		} catch (Exception e) {
			LOG.error("[CRAFT-ATOM-RPC] Rpc server start fail, exit!", e);
			System.exit(0);
		}
	}

	@Override
	public void expose(Class<?> rpcInterface, Object rpcObject, RpcOption rpcOption) {
		Method[] methods = rpcInterface.getMethods();
		for (Method method : methods) {
			RpcMethod rpcMethod = new RpcMethod();
			rpcMethod.setName(method.getName());
			rpcMethod.setParameterTypes(method.getParameterTypes());
			rpcMethod.setReturnType(method.getReturnType());
			expose(rpcInterface, rpcMethod, rpcObject, rpcOption);
		}
		
	}

	@Override
	public void expose(Class<?> rpcInterface, RpcMethod rpcMethod, Object rpcObject, RpcOption rpcOption) {
		RpcEntry entry = new RpcEntry();
		entry.setRpcInterface(rpcInterface);
		entry.setRpcMethod(rpcMethod);
		entry.setRpcObject(rpcObject);
		entry.setRpcOption(rpcOption);
		String key = registry.key(rpcInterface, rpcMethod);
		registry.register(key, entry);	
	}

}

@@ -1385,16 +1385,28 @@
 0 * 1000
+            
 ;%0A%09%09invo
@@ -1411,16 +1411,24 @@
 voker   
+        
 = new De
@@ -1444,16 +1444,18 @@
 nvoker()
+  
 ;%0A%09%09prot
@@ -1460,16 +1460,24 @@
 otocol  
+        
 = new De
@@ -1494,16 +1494,17 @@
 otocol()
+ 
 ;%0A%09%09proc
@@ -1509,16 +1509,24 @@
 ocessor 
+        
 = new De
@@ -1558,16 +1558,24 @@
 ceptor  
+        
 = new De
@@ -1588,24 +1588,25 @@
 pcAcceptor()
+ 
 ;%0A%09%09registry
@@ -1607,16 +1607,24 @@
 gistry  
+        
 = RpcReg
@@ -1640,24 +1640,27 @@
 Instance();%0A
+%09%09%0A
 %09%09acceptor .
@@ -1717,16 +1717,18 @@
 rotocol)
+  
 ;%0A%09%09proc
@@ -1752,16 +1752,20 @@
 invoker)
+    
 ;%0A%09%7D%0A%09%0A%09
@@ -2528,19 +2528,16 @@
 n);%0A%09%09%7D%0A
-%09%09%0A
 %09%7D%0A%0A%09@Ov

fix - code style