package com.dianping.cat.configuration;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public enum NetworkInterfaceManager {
	INSTANCE;

	private InetAddress m_local;

	private NetworkInterfaceManager() {
		load();
	}

	public String getLocalHostAddress() {
		return m_local.getHostAddress();
	}

	public String getLocalHostName() {
		try {
			return InetAddress.getLocalHost().getHostName();
		} catch (UnknownHostException e) {
			return m_local.getHostName();
		}
	}

	private void load() {
		String ip = System.getProperty("host.ip");

		if (ip != null) {
			try {
				m_local = InetAddress.getByName(ip);
				return;
			} catch (Exception e) {
				System.err.println(e);
				// ignore
			}
		}

		try {
			List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
			List<InetAddress> addresses = new ArrayList<InetAddress>();
			InetAddress local = null;
			
			try {
				for (NetworkInterface ni : nis) {
					if (ni.isUp()) {
						addresses.addAll(Collections.list(ni.getInetAddresses()));
					}
				}
				local = findValidateIp(addresses);
			} catch (Exception e) {
				// ignore
			}
			m_local = local;
		} catch (SocketException e) {
			// ignore it
		}
	}

	public InetAddress findValidateIp(List<InetAddress> addresses) {
		InetAddress local = null;
		for (InetAddress address : addresses) {
			if (address instanceof Inet4Address) {
				if (address.isLoopbackAddress() || address.isSiteLocalAddress()) {
					if (local == null) {
						local = address;
					} else if (address.isSiteLocalAddress() && !address.isLoopbackAddress()) {
						// site local address has higher priority than other address
						local = address;
					} else if (local.isSiteLocalAddress() && address.isSiteLocalAddress()) {
						// site local address with a host name has higher
						// priority than one without host name
						if (local.getHostName().equals(local.getHostAddress())
						      && !address.getHostName().equals(address.getHostAddress())) {
							local = address;
						}
					}
				} else {
					if (local == null) {
						local = address;
					}
				}
			}
		}
		return local;
	}
}

@@ -664,16 +664,201 @@
 %09%09%7D%0A%09%7D%0A%0A
+%09public String getProperty(String name) %7B%0A%09%09String value = null;%0A%0A%09%09value = System.getProperty(name);%0A%09%09%0A%09%09if (value == null) %7B%0A%09%09%09value = System.getenv(name);%0A%09%09%7D%0A%0A%09%09return value;%0A%09%7D%0A%0A
 %09private
@@ -886,23 +886,16 @@
 ng ip = 
-System.
 getPrope
@@ -1262,19 +1262,16 @@
 = null;%0A
-%09%09%09
 %0A%09%09%09try 

modify the network interface manager