package com.vinsol.expensetracker.sync;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import android.content.Context;
import android.os.AsyncTask;
import com.google.gson.Gson;
import com.vinsol.confconnect.gson.MyGson;
import com.vinsol.confconnect.http.HTTP;
import com.vinsol.expensetracker.ExpenseTrackerApplication;
import com.vinsol.expensetracker.R;
import com.vinsol.expensetracker.helpers.CameraFileSave;
import com.vinsol.expensetracker.helpers.ConvertCursorToListString;
import com.vinsol.expensetracker.helpers.DatabaseAdapter;
import com.vinsol.expensetracker.helpers.FileHelper;
import com.vinsol.expensetracker.helpers.SharedPreferencesHelper;
import com.vinsol.expensetracker.models.Data;
import com.vinsol.expensetracker.models.Entry;
import com.vinsol.expensetracker.models.Favorite;
import com.vinsol.expensetracker.models.Sync;
import com.vinsol.expensetracker.utils.Log;
import com.vinsol.expensetracker.utils.Strings;
public class SyncHelper extends AsyncTask<Void, Void, Void>{
private static Context context;
private DatabaseAdapter adapter;
private HTTP http;
private ConvertCursorToListString convertCursorToListString;
private Gson gson;
private FileHelper fileHelper;
public static AsyncTask<Void, Void, Void> syncHelper;
public static boolean toConinue = false;
public SyncHelper(Context context) {
SyncHelper.context = context;
convertCursorToListString = new ConvertCursorToListString(context);
adapter = new DatabaseAdapter(context);
http = new HTTP(context);
gson = new MyGson().get();
fileHelper = new FileHelper();
}
@Override
protected Void doInBackground(Void... params) {
Log.d("************************** Starting Sync **********************************");
try {
pull();
push();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private void pull() throws IOException {
pullData();
pullFiles();
}
private void pullData() throws IOException {
Log.d("*********************** Getting SyncData **********************************");
String fetchedSyncResponse = http.getSyncData();
Log.d(" ************* "+ fetchedSyncResponse);
Sync sync = gson.fromJson(fetchedSyncResponse, Sync.class);
if(sync != null) {
SharedPreferencesHelper.setSyncTimeStamp(sync.timestamp);
Log.d(" ******************** Started Adding Expenses To DB ****************************** ");
Long startTimeInMilis = Calendar.getInstance().getTimeInMillis();
addExpenses(sync.add.expenses,true);
addFavorites(sync.add.favorites,true);
updateExpenses(sync.update.expenses);
updateFavorites(sync.update.favorites);
deleteExpenses(sync.delete.expenses);
deleteFavorites(sync.delete.favorites);
Log.d(" ******************** Total Time Taken ****************************** "+(Calendar.getInstance().getTimeInMillis() - startTimeInMilis));
Log.d(" ******************** Finished Adding Expenses To DB ****************************** ");
}
}
private void pullFiles() {
Log.d("*********************** Pulling Files **********************************");
List<Entry> entries = convertCursorToListString.getEntryListFilesToDownload();
for(Entry entry : entries) {
Log.d("***** entry id "+entry.id+" "+entry.idFromServer);
if(Strings.equal(entry.type, context.getString(R.string.voice))) {
Log.d("***** entry id "+entry.id+" "+entry.idFromServer);
try {
if(http.downloadExpenseFile(entry.id, entry.idFromServer, true)) {
entry.fileToDownload = false;
entry.fileUploaded = true;
updateEntry(entry);
}
} catch (IOException e) {
e.printStackTrace();
}
}
if(Strings.equal(entry.type, context.getString(R.string.camera))) {
try {
if(http.downloadExpenseFile(entry.id, entry.idFromServer, false)) {
new CameraFileSave(context).resizeImageAndSaveThumbnails(entry.id, false);
entry.fileToDownload = false;
entry.fileUploaded = true;
updateEntry(entry);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
List<Favorite> favorites = convertCursorToListString.getFavoriteListFilesToDownload();
for(Favorite favorite : favorites) {
if(Strings.equal(favorite.type, context.getString(R.string.voice))) {
try {
if(http.downloadFavoriteFile(favorite.id, favorite.idFromServer, true)) {
favorite.fileToDownload = false;
favorite.fileUploaded = true;
updateFavorite(favorite);
}
} catch (IOException e) {
e.printStackTrace();
}
}
if(Strings.equal(favorite.type, context.getString(R.string.camera))) {
try {
if(http.downloadFavoriteFile(favorite.id, favorite.idFromServer, false)) {
new CameraFileSave(context).resizeImageAndSaveThumbnails(favorite.id, true);
favorite.fileToDownload = false;
favorite.fileUploaded = true;
updateFavorite(favorite);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Log.d("*********************** Pulling Files **********************************");
}
private void updateEntry(Entry entry) {
adapter.open();
adapter.editExpenseEntryById(entry);
adapter.close();
}
private void updateFavorite(Favorite favorite) {
adapter.open();
adapter.editFavoriteEntryById(favorite);
adapter.close();
}
private void push() throws IOException {
pushData();
pushFiles();
}
private void pushData() throws IOException {
Log.d("****************** Pushing Data ****************");
create();
update();
delete();
Log.d("****************** Data Pushed ****************");
}
private void create() {
createEntry();
createFavorites();
}
//Push request to update records
private void update() {
updateEntry();
updateFavorites();
}
private void updateEntry() {
List<Entry> entries = convertCursorToListString.getEntryListNotSyncedAndUpdated();
if(entries.size() > 0) {
String data = gson.toJson(entries);
Log.d(data +" size "+convertCursorToListString.getEntryListNotSyncedAndUpdated().size());
if(data != null) {
try {
String fetchedData = http.updateMultipleExpenses(data);
if(fetchedData != null) {
Data response = gson.fromJson(fetchedData,Data.class);
updateExpenses(response.expenses);
Log.d(fetchedData + " en ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void updateFavorites() {
List<Favorite> favorites = convertCursorToListString.getFavoriteListNotSyncedAndUpdated();
if(favorites.size() > 0) {
String data = gson.toJson(favorites);
Log.d(data +" size "+convertCursorToListString.getFavoriteListNotSyncedAndUpdated().size());
if(data != null) {
try {
String fetchedData = http.updateMultipleFavorites(data);
if(fetchedData != null) {
Data response = gson.fromJson(fetchedData,Data.class);
updateFavorites(response.favorites);
Log.d(fetchedData + " en ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//Push request to delete records
private void delete() {
deleteEntry();
deleteFavorites();
}
private void deleteEntry() {
List<Entry> entries = convertCursorToListString.getEntryListNotSyncedAndDeleted();
Log.d("************************* Deleting ***************************");
if(entries.size() > 0) {
String data = gson.toJson(entries);
Log.d(data +" size "+convertCursorToListString.getEntryListNotSyncedAndDeleted().size());
if(data != null) {
try {
String fetchedData = http.deleteMultipleExpenses(data);
if(fetchedData != null) {
Data response = gson.fromJson(fetchedData,Data.class);
deleteExpenses(response.expenses);
Log.d(fetchedData + " en ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void deleteFavorites() {
List<Favorite> favorites = convertCursorToListString.getFavoriteListNotSyncedAndDeleted();
if(favorites.size() > 0) {
String data = gson.toJson(favorites);
Log.d(data +" size "+convertCursorToListString.getFavoriteListNotSyncedAndDeleted().size());
if(data != null) {
try {
String fetchedData = http.deleteMultipleFavorites(data);
if(fetchedData != null) {
Data response = gson.fromJson(fetchedData,Data.class);
deleteFavorites(response.favorites);
Log.d(fetchedData + " en ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//Push Request to create new records which are not synced
private void createEntry() {
List<Entry> entries = convertCursorToListString.getEntryListNotSyncedAndCreated();
if(entries.size() > 0) {
String data = gson.toJson(entries);
Log.d(data +" size "+convertCursorToListString.getEntryListNotSyncedAndCreated().size());
if(data != null) {
try {
String fetchedData = http.addMultipleExpenses(data);
if(fetchedData != null) {
Data response = gson.fromJson(fetchedData,Data.class);
updateExpenses(response.expenses);
Log.d(fetchedData + " en ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void createFavorites() {
List<Favorite> favorites = convertCursorToListString.getFavoriteListNotSyncedAndCreated();
if(favorites.size() > 0) {
String data = gson.toJson(favorites);
Log.d(data +" size "+convertCursorToListString.getFavoriteListNotSyncedAndCreated().size());
if(data != null) {
try {
String fetchedData = http.addMultipleFavorites(data);
Log.d(fetchedData + " en ");
if(fetchedData != null) {
Data response = gson.fromJson(fetchedData,Data.class);
updateFavorites(response.favorites);
Log.d(fetchedData + " en ");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void pushFiles() {
uploadExpenseFiles();
uploadFavoriteFiles();
}
private void uploadExpenseFiles() {
List<Entry> entries = convertCursorToListString.getEntryListFileNotUploaded();
List<Entry> entriesToUpdate = new ArrayList<Entry>();
boolean toUpdate = false;
for(Entry entry : entries) {
if(!Strings.equal(entry.syncBit, context.getString(R.string.syncbit_synced))) { continue; }
toUpdate = true;
boolean isAudio;
if(Strings.equal(entry.type, context.getString(R.string.voice))) {
isAudio = true;
} else if(Strings.equal(entry.type, context.getString(R.string.camera))) {
isAudio = false;
} else {
continue;
}
String response;
try {
if(!isAudio) {
response = http.uploadExpenseFile(fileHelper.getCameraFileLargeEntry(entry.id), entry.idFromServer, isAudio);
} else {
response = http.uploadExpenseFile(fileHelper.getAudioFileEntry(entry.id), entry.idFromServer, isAudio);
}
Log.d("******************* Getting Response *******************");
if(response != null) {
Log.d(response);
Entry responseEntry = gson.fromJson(response, Entry.class);
entriesToUpdate.add(responseEntry);
}
} catch (IOException e) {
e.printStackTrace();
}
}
if(toUpdate) updateExpenses(entriesToUpdate);
}
private void uploadFavoriteFiles() {
List<Favorite> favorites = convertCursorToListString.getFavoriteListFileNotUploaded();
List<Favorite> favoritesToUpdate = new ArrayList<Favorite>();
boolean toUpdate = false;
for(Favorite favorite : favorites) {
if(!Strings.equal(favorite.syncBit, context.getString(R.string.syncbit_synced))) { continue; }
toUpdate = true;
boolean isAudio;
if(Strings.equal(favorite.type, context.getString(R.string.voice))) {
isAudio = true;
} else if(Strings.equal(favorite.type, context.getString(R.string.camera))) {
isAudio = false;
} else {
continue;
}
String response;
try {
if(!isAudio) {
response = http.uploadFavoriteFile(fileHelper.getCameraFileLargeFavorite(favorite.id), favorite.idFromServer, isAudio);
} else {
response = http.uploadFavoriteFile(fileHelper.getAudioFileFavorite(favorite.id), favorite.idFromServer, isAudio);
}
Log.d("******************* Getting Response *******************");
if(response != null) {
Log.d(response);
Favorite responseFavorite = gson.fromJson(response, Favorite.class);
favoritesToUpdate.add(responseFavorite);
}
} catch (IOException e) {
e.printStackTrace();
}
}
if(toUpdate) updateFavorites(favoritesToUpdate);
}
@Override
protected void onPostExecute(Void result) {
Log.d("************************** Finishing Sync **********************************");
super.onPostExecute(result);
if(toConinue) {
toConinue = false;
SyncHelper.syncHelper = new SyncHelper(context).execute();
}
}
private void addExpenses(List<Entry> entries,boolean isPull) {
adapter.open();
for(Entry entry : entries) {
// if(isPull) {
// setSyncBitAndFileDownloaded(entry);
// } else {
// setSyncBit(entry);
// }
setSyncBit(entry);
Log.d("*************************"+"fileToDOwnload "+entry.fileToDownload);
String tempId = adapter.getEntryIdByHash(entry.myHash);
if(Strings.isEmpty(tempId)) {
adapter.insertToEntryTable(entry);
} else {
entry.id = tempId;
adapter.editExpenseEntryById(entry);
}
}
adapter.close();
}
private void addFavorites(List<Favorite> favorites, boolean isPull) {
adapter.open();
for(Favorite favorite : favorites) {
// if(isPull) {
// setSyncBitAndFileDownloaded(favorite);
// } else {
// setSyncBit(favorite);
// }
setSyncBit(favorite);
String tempId = adapter.getFavIdByHash(favorite.myHash);
if(Strings.isEmpty(tempId)) {
adapter.insertToFavoriteTable(favorite);
} else {
favorite.id = tempId;
adapter.editFavoriteEntryByHash(favorite);
}
}
adapter.close();
}
private void updateExpenses(List<Entry> entries) {
adapter.open();
for(Entry entry : entries) {
Entry tempEntry = convertCursorToListString.getSingleEntryByHash(entry.myHash);
boolean toFetchFile = true;
if(tempEntry != null && Strings.equal(entry.fileUpdatedAt, tempEntry.fileUpdatedAt)) {
toFetchFile = false;
}
if(toFetchFile) {
setSyncBitAndFileDownloaded(entry);
} else {
setSyncBit(entry);
}
setSyncBit(entry);
entry.id = tempEntry.id;
entry.favorite = adapter.getFavIdByHash(entry.favorite);
adapter.editExpenseEntryByHash(entry);
}
adapter.close();
}
private void updateFavorites(List<Favorite> favorites) {
Log.d("***************** Check ");
Log.d("favorite "+adapter+" "+favorites);
adapter.open();
for(Favorite favorite : favorites) {
Favorite tempFavorite = convertCursorToListString.getSingleFavoriteByHash(favorite.myHash);
boolean toFetchFile = true;
if(tempFavorite != null && Strings.equal(favorite.fileUpdatedAt, tempFavorite.fileUpdatedAt)) {
toFetchFile = false;
}
if(toFetchFile) {
setSyncBitAndFileDownloaded(favorite);
} else {
setSyncBit(favorite);
}
setSyncBit(favorite);
favorite.id = tempFavorite.id;
adapter.editFavoriteEntryByHash(favorite);
}
adapter.close();
}
private void deleteFavorites(List<Favorite> favorites) {
adapter.open();
for(Favorite favorite : favorites) {
setSyncBit(favorite);
// favorite.id = adapter.getFavIdByHash(favorite.myHash);
// if(Strings.equal(favorite.type, context.getString(R.string.voice)) || Strings.equal(favorite.type, context.getString(R.string.camera))) {
// fileHelper.deleteAllFavoriteFiles(favorite.id);
// }
// adapter.permanentDeleteFavoriteTableEntryID(favorite.id);
}
adapter.close();
}
private void deleteExpenses(List<Entry> entries) {
adapter.open();
for(Entry entry : entries) {
setSyncBit(entry);
// entry.id = adapter.getEntryIdByHash(entry.myHash);
// if(Strings.equal(entry.type, context.getString(R.string.voice)) || Strings.equal(entry.type, context.getString(R.string.camera))) {
// fileHelper.deleteAllEntryFiles(entry.id);
// }
// adapter.permanentDeleteEntryTableEntryID(entry.id);
}
adapter.close();
}
private void setSyncBitAndFileDownloaded(Entry entry) {
setSyncBit(entry);
setDownloaded(entry);
setUploaded(entry);
}
private void setSyncBitAndFileDownloaded(Favorite favorite) {
setSyncBit(favorite);
setDownloaded(favorite);
setUploaded(favorite);
}
private void setDownloaded(Entry entry) {
// entry.fileToDownload = true;
}
private void setDownloaded(Favorite favorite) {
// favorite.fileToDownload = true;
}
private void setUploaded(Entry entry) {
entry.fileUploaded = true;
}
private void setUploaded(Favorite favorite) {
favorite.fileUploaded = true;
}
private void setSyncBit(Entry entry) {
entry.syncBit = context.getString(R.string.syncbit_synced);
}
private void setSyncBit(Favorite favorite) {
favorite.syncBit = context.getString(R.string.syncbit_synced);
}
public static void startSync() {
if(ExpenseTrackerApplication.toSync) {
if(SyncHelper.syncHelper.getStatus().equals(AsyncTask.Status.RUNNING)) {
toConinue = true;
} else {
toConinue = false;
SyncHelper.syncHelper = new SyncHelper(context).execute();
}
}
}
}