package com.growthpush;

import java.io.FileOutputStream;
import java.io.IOException;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;

import com.growthpush.model.Client;
import com.growthpush.model.Tag;
import com.growthpush.utils.IOUtils;

public class Preference {

	private static final String FILE_NAME = "growthpush-preferences";
	private static final String CLIENT_KEY = "client";
	private static final String TAG_KEY = "tags";

	private static Preference instance = new Preference();

	private Context context = null;
	private JSONObject preferences = null;

	private Preference() {
		super();
	}

	public static Preference getInstance() {
		return instance;
	}

	public void setContext(Context context) {
		this.context = context;
	}

	public Client fetchClient() {

		Client client = new Client();
		client.setJsonObject(fetch(CLIENT_KEY));
		return client;

	}

	public Tag fetchTag(String name) {

		JSONObject tags = fetch(TAG_KEY);
		if (tags == null)
			return null;
		if (!tags.has(name))
			return null;

		Tag tag = new Tag();
		try {
			tag.setJsonObject(tags.getJSONObject(name));
		} catch (JSONException e) {
		}

		return tag;

	}

	public void saveClient(Client client) {
		save(CLIENT_KEY, client.getJsonObject());
	}

	public void saveTag(Tag tag) {

		JSONObject tags = fetch(TAG_KEY);
		if (tags == null)
			tags = new JSONObject();

		try {
			tags.put(tag.getName(), tag.getJsonObject());
		} catch (JSONException e) {
		}

		save(TAG_KEY, tags);

	}

	private JSONObject fetch(String key) {

		try {
			return getPreferences().getJSONObject(key);
		} catch (JSONException e) {
			return null;
		}

	}

	private void save(String key, JSONObject jsonObject) {

		JSONObject preferences = getPreferences();
		try {
			preferences.put(key, jsonObject);
		} catch (JSONException e) {
			return;
		}

		synchronized (this) {
			try {
				FileOutputStream fileOutputStream = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
				fileOutputStream.write(preferences.toString().getBytes());
				fileOutputStream.flush();
			} catch (IOException e) {
			}
		}

	}

	private JSONObject getPreferences() {

		if (context == null)
			throw new IllegalStateException("Context is null.");

		synchronized (this) {

			if (this.preferences == null) {
				try {
					String json = IOUtils.toString(context.openFileInput(FILE_NAME));
					this.preferences = new JSONObject(json);
				} catch (IOException e) {
				} catch (JSONException e) {
				}
			}

			if (this.preferences == null)
				this.preferences = new JSONObject();

		}

		return preferences;

	}
}

@@ -1193,32 +1193,45 @@
 g;%0A%0A%09%7D%0A%0A%09public 
+synchronized 
 void saveClient(
@@ -1247,16 +1247,114 @@
 ient) %7B%0A
+%0A%09%09if (client == null)%0A%09%09%09throw new IllegalArgumentException(%22Argument client cannot be null.%22);%0A%0A
 %09%09save(C
@@ -1389,16 +1389,17 @@
 ect());%0A
+%0A
 %09%7D%0A%0A%09pub
@@ -1398,24 +1398,37 @@
 %09%7D%0A%0A%09public 
+synchronized 
 void saveTag
@@ -1436,24 +1436,115 @@
 Tag tag) %7B%0A%0A
+%09%09if (tag == null)%0A%09%09%09throw new IllegalArgumentException(%22Argument tag cannot be null.%22);%0A%0A
 %09%09JSONObject
@@ -2347,32 +2347,45 @@
 %7D%0A%0A%09%7D%0A%0A%09private 
+synchronized 
 JSONObject getPr
@@ -2483,34 +2483,8 @@
 );%0A%0A
-%09%09synchronized (this) %7B%0A%0A%09
 %09%09if
@@ -2516,24 +2516,22 @@
 l) %7B%0A%09%09%09
-%09
 try %7B%0A
-%09
 %09%09%09%09Stri
@@ -2596,17 +2596,16 @@
 ));%0A%09%09%09%09
-%09
 this.pre
@@ -2637,17 +2637,16 @@
 (json);%0A
-%09
 %09%09%09%7D cat
@@ -2669,17 +2669,16 @@
 e) %7B%0A%09%09%09
-%09
 %7D catch 
@@ -2704,20 +2704,17 @@
 %0A%09%09%09
-%09
 %7D%0A
-%09
 %09%09%7D%0A%0A%09%09
-%09
 if (
@@ -2739,17 +2739,16 @@
 = null)%0A
-%09
 %09%09%09this.
@@ -2780,21 +2780,16 @@
 ect();%0A%0A
-%09%09%7D%0A%0A
 %09%09return

Fix ConcurrentModificationException of Preference#saveTag