package me.yoqi.wifiproxy.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;

/**
 * 代理设置
 * 
 * @author liuyuqi
 *
 */
public class ProxySetting {

	private static Object proxySettings;

	/**
	 * 设置公有成员值
	 * 
	 * @param obj
	 * @param value
	 * @param name
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static void setEnumField(Object obj, String value, String name)
			throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
		Field f = obj.getClass().getField(name);
		f.set(obj, Enum.valueOf((Class<Enum>) f.getType(), value));
	}

	/**
	 * 获取public字段
	 * 
	 * @param obj
	 * @param name
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static Object getFieldObject(Object obj, String name)
			throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
		Field f = obj.getClass().getField(name);
		Object out = f.get(obj);
		return out;
	}

	/**
	 * 获取当前WiFi状态
	 * 
	 * @param wifiManager
	 * @return
	 */
	public static WifiConfiguration getCurrentWifiConfiguration(WifiManager wifiManager) {
		if (!wifiManager.isWifiEnabled())
			return null;// 没有打开wifi
		List<WifiConfiguration> configurationList = wifiManager.getConfiguredNetworks();
		WifiConfiguration configuration = null;
		int cur = wifiManager.getConnectionInfo().getNetworkId();
		for (int i = 0; i < configurationList.size(); ++i) {
			WifiConfiguration wifiConfiguration = configurationList.get(i);
			if (wifiConfiguration.networkId == cur)
				configuration = wifiConfiguration;
		}
		return configuration;
	}

	/**
	 * 设置wifi代理 API>17
	 * 
	 * @param context
	 * @param host
	 *            代理ip
	 * @param port
	 *            代理端口
	 * @param exclList
	 *            添加不用代理的网址
	 */
	public static void setWifiProxySettingsFor17And(Context context, String host, int port, String exclList) {
		WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		WifiConfiguration config = getCurrentWifiConfiguration(wifiManager);
		if (config == null)
			return;
		try {
			Object linkProperties = getFieldObject(config, "linkProperties");
			if (null == linkProperties)
				return;
			// 获取类 LinkProperties的setHttpProxy方法
			Class<?> proxyPropertiesClass = Class.forName("android.net.ProxyProperties");
			Class<?>[] setHttpProxyParams = new Class[1];
			setHttpProxyParams[0] = proxyPropertiesClass;
			Class<?> lpClass = Class.forName("android.net.LinkProperties");
			Method setHttpProxy = lpClass.getDeclaredMethod("setHttpProxy", setHttpProxyParams);
			setHttpProxy.setAccessible(true);
			// 获取类 ProxyProperties的构造函数
			Constructor<?> proxyPropertiesCtor = proxyPropertiesClass.getConstructor(String.class, int.class,
					String.class);
			// 实例化类ProxyProperties
			proxySettings = proxyPropertiesCtor.newInstance(host, port, exclList);
			Object[] params = new Object[1];
			params[0] = proxySettings;
			setHttpProxy.invoke(linkProperties, params);
			setEnumField(config, "STATIC", "proxySettings");
			// save the settings
			wifiManager.updateNetwork(config);
			wifiManager.disconnect();
			wifiManager.reconnect();
		} catch (Exception e) {
		}
	}

	/**
	 * 取消代理设置
	 * 
	 * @param context
	 */
	public static void unsetWifiProxySettingsFor17And(Context context) {
		WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		WifiConfiguration config = getCurrentWifiConfiguration(wifiManager);
		if (null == config)
			return;
		try {
			Object linkProperties = getFieldObject(config, "linkProperties");
			if (null == linkProperties)
				return;
			// get the setHttpProxy method for LinkProperties
			Class<?> proxyPropertiesClass = Class.forName("android.net.ProxyProperties");
			Class<?>[] setHttpProxyParams = new Class[1];
			setHttpProxyParams[0] = proxyPropertiesClass;
			Class<?> lpClass = Class.forName("android.net.LinkProperties");
			Method setHttpProxy = lpClass.getDeclaredMethod("setHttpProxy", setHttpProxyParams);
			setHttpProxy.setAccessible(true);
			// pass null as the proxy
			Object[] params = new Object[1];
			params[0] = null;
			setHttpProxy.invoke(linkProperties, params);
			setEnumField(config, "NONE", "proxySettings");
			// save the config
			wifiManager.updateNetwork(config);
			wifiManager.disconnect();
			wifiManager.reconnect();
		} catch (Exception e) {
		}
	}
}
