package nc.bs.framework.rmi;

import java.net.MalformedURLException;

import nc.bs.framework.common.RuntimeEnv;
import nc.bs.framework.exception.ConnectorException;
import nc.pub.framework.client.dispatch.ClientDispatchCfgUtil;
import nc.vo.jcom.lang.StringUtil;

/**
 * 
 * @author He Guan Yu
 * 
 * @date May 7, 2010
 * 
 */
public class GroupBasedRemoteAddressSelector implements RemoteAddressSelector {

	private static final long serialVersionUID = -300090652128749483L;

	private Address dispatchAddress;

	private String serverGroup;

	private String serviceName;

	public GroupBasedRemoteAddressSelector(String serviceName, Address addr, String serverGroup) {
		this.serviceName = serviceName;
		this.dispatchAddress = addr;
		this.serverGroup = serverGroup;
	}

	@Override
	public Address select() throws ConnectorException {
		Address t = dispatchAddress;
		String group = serverGroup;
		// dynamic select
		Address clientDispatchAddr = getDispatchTarget(serviceName, t);
		if (clientDispatchAddr != null) {
			t = clientDispatchAddr;
		}
		String clientDispatchGroup = getDispatchGroup(serviceName);
		if (!StringUtil.isEmptyWithTrim(clientDispatchGroup)) {
			group = clientDispatchGroup;
		}

		try {
			if (group != null && !"framework".equals(group)) {
				if (t.getPath().endsWith("/")) {
					t = new Address(t + group);
				} else {
					t = new Address(t + "/" + group);
				}
			}
		} catch (MalformedURLException e) {

		}

		return t;
	}

	private String getDispatchGroup(String serviceName) {
		if (!RuntimeEnv.getInstance().isRunningInServer()) {
			String disGroup = ClientDispatchCfgUtil.getGroup(serviceName);
			if (!StringUtil.isEmptyWithTrim(disGroup)) {
				return disGroup;
			}
		}
		return "";
	}

	private Address getDispatchTarget(String serviceName, Address dispatchUrl) {
		/** client dispatch **/
		if (!RuntimeEnv.getInstance().isRunningInServer()) {
			// !"nc.bs.framework.core.common.IConfigMetaService"
			// .equalsIgnoreCase(metaVO.getName())
			String disUrl = ClientDispatchCfgUtil.getURL(serviceName, dispatchUrl);
			if (!StringUtil.isEmptyWithTrim(disUrl)) {
				try {
					return new Address(disUrl);
				} catch (MalformedURLException e) {
					return null;
				}
			}
		}
		return null;
	}

	@Override
	public void fail(Address url) {
	}

	public int hashCode() {
		return (serverGroup == null ? 0 : serverGroup.hashCode()) + dispatchAddress.hashCode();
	}

	public boolean equals(Object other) {
		if (other instanceof GroupBasedRemoteAddressSelector) {
			GroupBasedRemoteAddressSelector ga = (GroupBasedRemoteAddressSelector) other;
			if (ga.dispatchAddress.equals(dispatchAddress)) {
				return equals(ga.serverGroup, serverGroup);
			}
		}
		return false;
	}

	private boolean equals(String a, String b) {
		if (a == null) {
			return b == null;
		} else {
			return a.equals(b);
		}
	}
}
