package guard.api.sensitive.ui.sapiguard.hookedapis;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import guard.api.sensitive.ui.sapiguard.utils.PrivacyManager;
import guard.api.sensitive.ui.sapiguard.XHook;
import guard.api.sensitive.ui.sapiguard.utils.XParam;

public class XLocationManager extends XHook {
	private Methods mMethod;
	private String mClassName;
	private static final String cClassName = "android.location.LocationManager";
	private static final Map<Object, Object> mMapProxy = new WeakHashMap<Object, Object>();

	private XLocationManager(Methods method, String restrictionName, String className) {
		super(restrictionName, method.name().replace("Srv_", ""), method.name());
		mMethod = method;
		mClassName = className;
	}

	public String getClassName() {
		return mClassName;
	}

	// @formatter:off

	// public void addGeofence(LocationRequest request, Geofence fence, PendingIntent intent)
	// public boolean addGpsStatusListener(GpsStatus.Listener listener)
	// public boolean addNmeaListener(GpsStatus.NmeaListener listener)
	// public void addProximityAlert(double latitude, double longitude, float radius, long expiration, PendingIntent intent)
	// public List<String> getAllProviders()
	// public String getBestProvider(Criteria criteria, boolean enabledOnly)
	// public GpsStatus getGpsStatus(GpsStatus status)
	// public Location getLastKnownLocation(String provider)
	// public List<String> getProviders(boolean enabledOnly)
	// public List<String> getProviders(Criteria criteria, boolean enabledOnly)
	// public boolean isProviderEnabled(String provider)
	// public void removeUpdates(LocationListener listener)
	// public void removeUpdates(PendingIntent intent)
	// public void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
	// public void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener, Looper looper)
	// public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, LocationListener listener, Looper looper)
	// public void requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent)
	// public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent)
	// public void requestSingleUpdate(String provider, LocationListener listener, Looper looper)
	// public void requestSingleUpdate(Criteria criteria, LocationListener listener, Looper looper)
	// public void requestSingleUpdate(String provider, PendingIntent intent)
	// public void requestSingleUpdate(Criteria criteria, PendingIntent intent)
	// public boolean sendExtraCommand(String provider, String command, Bundle extras)
	// frameworks/base/location/java/android/location/LocationManager.java
	// http://developer.android.com/reference/android/location/LocationManager.html

	// public void requestLocationUpdates(LocationRequest request, ILocationListener listener, android.app.PendingIntent intent, java.lang.String packageName)
	// public void removeUpdates(ILocationListener listener, android.app.PendingIntent intent, java.lang.String packageName)
	// public void requestGeofence(LocationRequest request, Geofence geofence, android.app.PendingIntent intent, java.lang.String packageName)
	// public void removeGeofence(Geofence fence, android.app.PendingIntent intent, java.lang.String packageName)
	// public Location getLastLocation(LocationRequest request, java.lang.String packageName)
	// public boolean addGpsStatusListener(IGpsStatusListener listener, java.lang.String packageName)
	// public void removeGpsStatusListener(IGpsStatusListener listener)
	// public java.util.List<java.lang.String> getAllProviders()
	// public java.util.List<java.lang.String> getProviders(Criteria criteria, boolean enabledOnly)
	// public java.lang.String getBestProvider(Criteria criteria, boolean enabledOnly)
	// public boolean isProviderEnabled(java.lang.String provider)
	// public boolean sendExtraCommand(java.lang.String provider, java.lang.String command, android.os.Bundle extras)
	// http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.4_r1/com/android/server/LocationManagerService.java
	// public boolean addGpsMeasurementsListener(IGpsMeasurementsListener listener, String packageName)
	// public boolean addGpsNavigationMessageListener(IGpsNavigationMessageListener listener, String packageName)
	// public boolean removeGpsMeasurementsListener(IGpsMeasurementsListener listener)
	// public boolean removeGpsNavigationMessageListener(IGpsNavigationMessageListener listener)
	// http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.0_r1/com/android/server/LocationManagerService.java

	// @formatter:on

	// @formatter:off
	private enum Methods {
		addGeofence, addGpsStatusListener, addNmeaListener, addProximityAlert,
		getAllProviders, getBestProvider, getProviders, isProviderEnabled,
		getGpsStatus,
		getLastKnownLocation,
		removeUpdates,
		requestLocationUpdates, requestSingleUpdate,
		sendExtraCommand,

		Srv_requestLocationUpdates, Srv_removeUpdates,
		Srv_requestGeofence, Srv_removeGeofence,
		Srv_getLastLocation,
		Srv_addGpsStatusListener, Srv_removeGpsStatusListener,
		Srv_getAllProviders, Srv_getProviders, Srv_getBestProvider, Srv_isProviderEnabled,
		Srv_sendExtraCommand,

		Srv_addGpsMeasurementsListener, Srv_addGpsNavigationMessageListener, Srv_removeGpsMeasurementsListener, Srv_removeGpsNavigationMessageListener
	};
	// @formatter:on

	public static List<XHook> getInstances(String className, boolean server) {
		List<XHook> listHook = new ArrayList<XHook>();
		if (!cClassName.equals(className)) {
			if (className == null)
				className = cClassName;

			for (Methods loc : Methods.values())
				if (loc == Methods.removeUpdates)
					listHook.add(new XLocationManager(loc, null, className));
				else if (loc.name().startsWith("Srv_remove")) {
					if (server)
						listHook.add(new XLocationManager(loc, null, "com.android.server.LocationManagerService"));
				} else if (loc.name().startsWith("Srv_")) {
					if (server)
						listHook.add(new XLocationManager(loc, PrivacyManager.cLocation,
								"com.android.server.LocationManagerService"));
				} else
					listHook.add(new XLocationManager(loc, PrivacyManager.cLocation, className));
		}
		return listHook;
	}




	@Override
	protected void before(XParam param) throws Throwable {




		switch (mMethod) {
		case addGeofence:
		case addProximityAlert:
		case Srv_requestGeofence:


		case Srv_removeGeofence:


		case addGpsStatusListener:
		case addNmeaListener:
		case Srv_addGpsStatusListener:
		case Srv_addGpsMeasurementsListener:
		case Srv_addGpsNavigationMessageListener:


		case Srv_removeGpsStatusListener:


		case Srv_removeGpsMeasurementsListener:


		case Srv_removeGpsNavigationMessageListener:

		case getAllProviders:
		case getBestProvider:
		case getGpsStatus:
		case getLastKnownLocation:
		case getProviders:
		case isProviderEnabled:
		case Srv_getAllProviders:
		case Srv_getProviders:
		case Srv_getBestProvider:
		case Srv_isProviderEnabled:
		case Srv_getLastLocation:
			// Do nothing
			break;

		case removeUpdates:

		case requestLocationUpdates:


		case Srv_removeUpdates:


		case Srv_requestLocationUpdates:


		case requestSingleUpdate:


		case sendExtraCommand:
		case Srv_sendExtraCommand:
			// Do nothing
			break;
		}
	}

	@Override
	protected void after(XParam param) throws Throwable {
		switch (mMethod) {
		case addGeofence:
		case addNmeaListener:
		case addGpsStatusListener:
		case addProximityAlert:
		case Srv_requestGeofence:
		case Srv_addGpsStatusListener:
		case Srv_addGpsMeasurementsListener:
		case Srv_addGpsNavigationMessageListener:
		case Srv_removeGeofence:
		case Srv_removeGpsStatusListener:
		case Srv_removeGpsMeasurementsListener:
		case Srv_removeGpsNavigationMessageListener:
			// Do nothing
			break;

		case isProviderEnabled:
		case Srv_isProviderEnabled:


		case getGpsStatus:


		case getProviders:
		case getAllProviders:
		case Srv_getAllProviders:
		case Srv_getProviders:

		case getBestProvider:
		case Srv_getBestProvider:


		case getLastKnownLocation:


		case Srv_getLastLocation:

		case removeUpdates:
		case requestLocationUpdates:
		case requestSingleUpdate:
		case Srv_removeUpdates:
		case Srv_requestLocationUpdates:

		case sendExtraCommand:
		case Srv_sendExtraCommand:

			break;
		}
	}

}
