/* 
 * Copyright 2011 by AVM GmbH <info@avm.de>
 *
 * This software contains free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License ("License") as 
 * published by the Free Software Foundation  (version 3 of the License). 
 * This software is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the copy of the 
 * License you received along with this software for more details.
 */

package de.avm.android.fritzapp.util;

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

/**
 * Identifier for a device using three unique IDs
 * 
 * 		IMEI - presence is optional
 * 		WiFi-MAC - presence is optional
 * 		Android-ID - may change on factory reset
 */
public class DeviceId
{
	private static final String TOKEN_DELIMITER = ";";
	private static final int ID_COUNT = 3;
	
	private String[] mIds = null;		// parsed ID created by this App
	private String mRaw = null;			// alien ID
	
	/**
	 * Creates instance for device running on
	 * 
	 * @param context
	 * @return
	 * 		the instance
	 */
	public static DeviceId create(Context context)
	{
		DeviceId result = new DeviceId();
		
		// IMEI
		String rawId = ((TelephonyManager)context
				.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
		if ((rawId != null) && (rawId.length() > 0))
			result.mIds[0] = rawId;

		// WiFi MAC
		WifiInfo wifiInfo = ((WifiManager)context
				.getSystemService(Context.WIFI_SERVICE)).getConnectionInfo();
		if ((wifiInfo != null) && !TextUtils.isEmpty(wifiInfo.getMacAddress()))
			result.mIds[1] = wifiInfo.getMacAddress(); 

		// Android ID
		rawId = Settings.Secure.getString(context.getContentResolver(),
				Settings.Secure.ANDROID_ID);
		if ((rawId != null) && (rawId.length() > 0))
			result.mIds[2] = rawId;

		return result;
	}
	
	/**
	 * Creates instance parsed from string representation
	 * @param string
	 * 		the string to pars
	 * @return
	 * 		the instance created or null if string is empty 
	 */
	public static DeviceId parse(String string)
	{
		if (TextUtils.isEmpty(string)) return null;
		
		try
		{
			DeviceId result = new DeviceId();
			String[] tokens = string.split(TOKEN_DELIMITER); 
			for (int ii = 0 ; ii < ID_COUNT; ii++)
				result.mIds[ii] = tokens[ii];
			return result;
		}
		catch(Exception e)
		{
			// ID created by another app
			DeviceId result = new DeviceId();
			result.mRaw = string;
			return result;
		}
	}

	/**
	 * Gets string representation of instance
	 */
	public String toString()
	{
		if (mRaw != null) return mRaw;
		
		StringBuilder string = new StringBuilder(); 
		for (int ii = 0 ; ii < ID_COUNT; ii++)
		{
			if (ii > 0) string.append(TOKEN_DELIMITER);
			string.append(mIds[ii]);
		}
		return string.toString();  
	}
	
	@Override
	public boolean equals(Object object)
	{
		if (this == object) return true;
		
		if (object instanceof DeviceId)
		{
			DeviceId id = (DeviceId)object;

			if (mRaw != null)
				return mRaw.equals(id.mRaw);
			
			for (int ii = 0 ; ii < ID_COUNT; ii++)
			{
				if (mIds[ii].equals(id.mIds[ii]))
					return true;
				if (!TextUtils.isEmpty(mIds[ii]) &&
						!TextUtils.isEmpty(id.mIds[ii]))
					break;
			}
		}

		return false;
	}
	
	@Override
	public int hashCode()
	{
		throw new UnsupportedOperationException();
	}

	private DeviceId()
	{
		mIds = new String[ID_COUNT];
		for (int ii = 0 ; ii < ID_COUNT; ii++) mIds[ii] = "";
	}
}
