package com.vaguehope.onosendai.provider;

import java.util.Set;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;

import com.vaguehope.onosendai.R;
import com.vaguehope.onosendai.config.Account;
import com.vaguehope.onosendai.provider.PostTask.PostResult;
import com.vaguehope.onosendai.provider.successwhale.PostToAccount;
import com.vaguehope.onosendai.provider.successwhale.SuccessWhaleProvider;
import com.vaguehope.onosendai.provider.twitter.TwitterProvider;
import com.vaguehope.onosendai.util.LogWrapper;

public class PostTask extends AsyncTask<Void, Void, PostResult> {

	private static final LogWrapper LOG = new LogWrapper("PT");

	private final Context context;
	private final PostRequest req;
	private final int notificationId;

	private NotificationManager notificationMgr;

	public PostTask (final Context context, final PostRequest req) {
		this.context = context;
		this.req = req;
		this.notificationId = (int) System.currentTimeMillis(); // Probably unique.
	}

	@Override
	protected void onPreExecute () {
		this.notificationMgr = (NotificationManager) this.context.getSystemService(Context.NOTIFICATION_SERVICE);
		Notification n = new NotificationCompat.Builder(this.context)
				.setSmallIcon(R.drawable.question_blue) // TODO better icon.
				.setContentTitle(String.format("Posting to %s...", this.req.getAccount().toHumanString()))
				.setOngoing(true)
				.setUsesChronometer(true)
				.build();
		this.notificationMgr.notify(this.notificationId, n);
	}

	@Override
	protected PostResult doInBackground (final Void... params) {
		switch (this.req.getAccount().getProvider()) {
			case TWITTER:
				return postTwitter();
			case SUCCESSWHALE:
				return postSuccessWhale();
			default:
				return new PostResult(this.req, new UnsupportedOperationException("Do not know how to post to account type: " + this.req.getAccount().toHumanString()));
		}
	}

	private PostResult postTwitter () {
		final TwitterProvider p = new TwitterProvider();
		try {
			p.post(this.req.getAccount(), this.req.getBody(), Long.parseLong(this.req.getInReplyToSid()));
			return new PostResult(this.req);
		}
		catch (Exception e) { // NOSONAR need to report all errors.
			return new PostResult(this.req, e);
		}
		finally {
			p.shutdown();
		}
	}

	private PostResult postSuccessWhale() {
		final SuccessWhaleProvider s = new SuccessWhaleProvider();
		try {
			s.post(this.req.getAccount(), this.req.getPostToAccounts(), this.req.getBody(), this.req.getInReplyToSid());
			return new PostResult(this.req);
		}
		catch (Exception e) { // NOSONAR need to report all errors.
			return new PostResult(this.req, e);
		}
		finally {
			s.shutdown();
		}
	}

	@Override
	protected void onPostExecute (final PostResult res) {
		if (!res.isSuccess()) {
			LOG.w("Post failed: %s", res.getE());
			PendingIntent contentIntent = PendingIntent.getActivity(this.context, 0, this.req.getRecoveryIntent(), 0);
			Notification n = new NotificationCompat.Builder(this.context)
					.setSmallIcon(R.drawable.exclamation_red) // TODO better icon.
					.setContentTitle(String.format("Tap to retry post to %s.", this.req.getAccount().toHumanString()))
					.setContentText(res.getE().getMessage())
					.setContentIntent(contentIntent)
					.setAutoCancel(true)
					.setUsesChronometer(false)
					.setWhen(System.currentTimeMillis())
					.build();
			this.notificationMgr.notify(this.notificationId, n);
		}
		else {
			this.notificationMgr.cancel(this.notificationId);
		}
	}

	public static class PostRequest {

		private final Account account;
		private final Set<PostToAccount> postToAccounts;
		private final String body;
		private final String inReplyToSid;
		private final Intent recoveryIntent;

		public PostRequest (final Account account, final Set<PostToAccount> postToAccounts, final String body, final String inReplyToSid, final Intent recoveryIntent) {
			this.account = account;
			this.postToAccounts = postToAccounts;
			this.body = body;
			this.inReplyToSid = inReplyToSid;
			this.recoveryIntent = recoveryIntent;
		}

		public Account getAccount () {
			return this.account;
		}

		public Set<PostToAccount> getPostToAccounts () {
			return this.postToAccounts;
		}

		public String getBody () {
			return this.body;
		}

		public String getInReplyToSid () {
			return this.inReplyToSid;
		}

		public Intent getRecoveryIntent () {
			return this.recoveryIntent;
		}

	}

	protected static class PostResult {

		private final boolean success;
		private final PostRequest request;
		private final Exception e;

		public PostResult (final PostRequest request) {
			this.success = true;
			this.request = request;
			this.e = null;
		}

		public PostResult (final PostRequest request, final Exception e) {
			this.success = false;
			this.request = request;
			this.e = e;
		}

		public boolean isSuccess () {
			return this.success;
		}

		public PostRequest getRequest () {
			return this.request;
		}

		public Exception getE () {
			return this.e;
		}

	}

}

@@ -2226,23 +2226,8 @@
 (), 
-Long.parseLong(
 this
@@ -2246,18 +2246,21 @@
 plyToSid
+Long
 (
-)
 ));%0A%09%09%09r
@@ -4482,24 +4482,189 @@
 ToSid;%0A%09%09%7D%0A%0A
+%09%09public long getInReplyToSidLong () %7B%0A%09%09%09if (this.inReplyToSid == null %7C%7C this.inReplyToSid.isEmpty()) return -1;%0A%09%09%09return Long.parseLong(this.inReplyToSid);%0A%09%09%7D%0A%0A
 %09%09public Int

Fix NumberFormatEx when posting.