package dt.call.aclient.background;

import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import dt.call.aclient.CallState;
import dt.call.aclient.Const;
import dt.call.aclient.Utils;
import dt.call.aclient.Vars;
import dt.call.aclient.background.async.HeartBeatAsync;
import dt.call.aclient.background.async.LoginAsync;
import dt.call.aclient.sqlite.SQLiteDb;
import dt.call.aclient.sqlite.DBLog;

/**
 * Created by Daniel on 4/13/16.
 *
 * Properly handle signin retries and heartbeat through recurring alarm instead of
 * unreliable timer task or Thread.sleep(5mins)
 */
public class AlarmReceiver extends BroadcastReceiver
{
	private static final String tag = "AlarmReceiver";

	//initially retry every 1, 5 then eventually 10 mins.
	private static final String INITIAL = "initial";
	private static final String SECOND = "second";
	private static final String INDEFINITE = "indefinite";
	private static String retryStage = INITIAL;
	private static int retried = 0;

	@Override
	public void onReceive(Context context, Intent intent)
	{
		AlarmManager manager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

		String action = intent.getStringExtra(Const.ALARM_ACTION);
		if(action.equals(Const.ALARM_ACTION_HEARTBEAT))
		{
			Utils.logcat(Const.LOGD, tag, "received heart beat alarm");
			if (!Vars.hasInternet)
			{
				Utils.logcat(Const.LOGW, tag, "no internet to try hearbeat on. SHOULD'VE EVEN BEEN TOLD TO DO SO");

				//no point of continuing the heart beat service if there is no internet
				manager.cancel(Vars.pendingHeartbeat);
				return;
			}

			//only send out a heartbeat if not in a call or waiting for one. don't want to send garbage on the media port
			// when there might be call data. it will probably produce weird sound
			if (Vars.state == CallState.NONE)
			{
				new HeartBeatAsync().execute();
			}

		}
		else if (action.equals(Const.ALARM_ACTION_RETRY))
		{
			//no point of a retry if there is no internet to try on
			if(!Vars.hasInternet)
			{
				Utils.logcat(Const.LOGD, tag, "no internet for sign in retry");
				manager.cancel(Vars.pendingRetries);

				//reset counters
				retryStage = INITIAL;
				retried = 0;

				//no point of doing the retry process if there is no internet
				manager.cancel(Vars.pendingRetries);
				return;
			}

			Utils.logcat(Const.LOGD, tag, "received retry alarm; stage: " + retryStage + " @ " + retried + " times");
			try
			{
				boolean loginok = new LoginAsync(Vars.uname, Vars.passwd, false).execute().get();
				if(!loginok)
				{
					retried++;

					/**
					 * Used tiered retry approach: initially try every minute. If that doesn't work out assume there is
					 * a temporary problem with either the server or that person's internet. Don't waste battery and try
					 * 5 mins. If after retrying every 5 mins doesn't work, then try every 10.
					 */
					if(retried == 5 && !retryStage.equals(INDEFINITE))
					{
						if(retryStage.equals(INITIAL))
						{
							manager.cancel(Vars.pendingRetries);
							manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Const.FIVE_MINS, Vars.pendingRetries);
							retryStage = SECOND;
							retried = 0;
						}
						else if(retryStage.equals(SECOND))
						{
							manager.cancel(Vars.pendingRetries);
							manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Const.TEN_MINS, Vars.pendingRetries);
							retryStage = INDEFINITE;
							retried = 0;
						}
					}
				}
				else
				{
					manager.cancel(Vars.pendingRetries);

					//reset counters
					retryStage = INITIAL;
					retried = 0;
				}
			}
			catch (Exception e)
			{
				Utils.logcat(Const.LOGE, tag, "problems trying login in: " + e.getClass().getName());
				Utils.dumpException(tag, e);
			}
		}
		else
		{
			Utils.logcat(Const.LOGW, tag, "received ??unknown?? alarm");
		}
	}
}

@@ -838,22 +838,19 @@
 c final 
-Str
 in
-g
+t
  INITIAL
@@ -856,17 +856,9 @@
 L = 
-%22initial%22
+1
 ;%0A%09p
@@ -877,22 +877,19 @@
 c final 
-Str
 in
-g
+t
  SECOND 
@@ -894,16 +894,9 @@
 D = 
-%22second%22
+2
 ;%0A%09p
@@ -915,22 +915,19 @@
 c final 
-Str
 in
-g
+t
  INDEFIN
@@ -936,20 +936,9 @@
 E = 
-%22indefinite%22
+3
 ;%0A%09p
@@ -951,22 +951,19 @@
  static 
-Str
 in
-g
+t
  retrySt
@@ -2921,16 +2921,17 @@
 = 5 && !
+(
 retrySta
@@ -2932,24 +2932,20 @@
 tryStage
-.equals(
+ == 
 INDEFINI
@@ -2979,24 +2979,20 @@
 tage
-.equals(
+ == 
 INITIAL)
 )%0A%09%09
@@ -2987,17 +2987,16 @@
 INITIAL)
-)
 %0A%09%09%09%09%09%09%7B
@@ -3251,24 +3251,19 @@
 tage
-.equals(
+ == 
 SECOND)
-)
 %0A%09%09%09

Switch from string comparison to int comparison for performance (even if just a bit).