package com.hmsoft.remote.rmi.rpc;

import java.util.HashSet;
import java.util.Set;

import com.hmsoft.common.bizinf.IExecuteLogic;
import com.hmsoft.common.bizlogic.RequestLogic;
import com.hmsoft.common.util.ExecuteRetryUtil;
import com.hmsoft.remote.rmi.exception.RemotingException;
import com.hmsoft.remote.rmi.future.IFuture;
import com.hmsoft.remote.rmi.handler.ExchangeHandler;
import com.hmsoft.remote.rmi.handler.HeaderExchangeHandler;
import com.hmsoft.remote.rmi.model.Request;
import com.hmsoft.remote.rmi.model.Response;
import com.hmsoft.remote.rmi.transport.NettyTransporter;

/**
 * 
 * ExchangeClient
 *
 */
public class ExchangeClient {

	private Client client;
	private static final int TIME_OUT = 3000;
	
	public ExchangeClient(String url, ExchangeHandler handler) {
		try {
			this.client = NettyTransporter.getInstance().connect(url, new HeaderExchangeHandler(handler));
		} catch (RemotingException e) {
			throw new IllegalArgumentException(e.getCause());
		}
	}
	
	/**
	 * 异步发送.
	 * @param message
	 * @throws RemotingException
	 */
    public void send(Object message) throws RemotingException {
        if (message instanceof Request
                || message instanceof Response) {
            this.client.send(message, false);
        } else {
            Request request = new Request();
            request.setVersion("1.0");
            request.setData(message);
            this.client.send(request, false);
        }
    }
	
    /**
     * 支持重试.
     * 发送返回future对象.
     * @param request
     * @param timeout
     * @return
     * @throws RemotingException
     */
    public Object requestTwoWay(Object request) throws RemotingException {
        // create request.
        Request req = new Request();
        req.setVersion("1.0");
        req.setTwoWay(true);
        req.setData(request);
        Set<String> excuteSet = new HashSet<String>();
        try {
            if (this.client.getChannel() == null) {
            	throw new RemotingException("发送失败，请重试");
            }
			final IExecuteLogic logic = new RequestLogic(req, this.client.getChannel());
			Object obj = ExecuteRetryUtil.execute(4, 5000, logic, excuteSet);
			return obj;
        } catch (RemotingException e) {
            throw e;
        }
    }
    
}
