package com.markupartist.sthlmtraveling.service;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.util.Log;
import com.markupartist.sthlmtraveling.provider.FavoritesDbAdapter;
import com.markupartist.sthlmtraveling.provider.JourneysProvider.Journey.Journeys;
import com.markupartist.sthlmtraveling.provider.TransportMode;
import com.markupartist.sthlmtraveling.provider.planner.JourneyQuery;
import org.json.JSONException;
import java.util.ArrayList;
public class DataMigrationService extends WakefulIntentService {
private static final String TAG = "DataMigrationService";
public DataMigrationService() {
super("data_migration");
}
@Override
void doWakefulWork(Intent intent) {
Context context = getApplicationContext();
maybeConvertFavorites(context);
Log.d(TAG, "Update complete...");
Intent updateUi = new Intent("sthlmtraveling.intent.action.UPDATE_UI");
updateUi.putExtra("sthlmtraveling.intent.extra.FAVORITES_UPDATED", true);
sendBroadcast(updateUi);
}
private void maybeConvertFavorites(Context context) {
if (!isFavoritesMigrated(context)) {
try {
convertFavorites(context);
} catch (Exception e) {
Log.w(TAG, "Failed to convert favorites. Mark as converted and move on.");
}
SharedPreferences settings = context.getSharedPreferences("sthlmtraveling", MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("converted_favorites", true);
editor.apply();
}
}
private void convertFavorites(Context context) {
Log.d(TAG, "About to convert favorites...");
FavoritesDbAdapter favoritesDbAdapter = new FavoritesDbAdapter(this);
favoritesDbAdapter.open();
Cursor cursor = favoritesDbAdapter.fetch();
if (cursor.moveToFirst()) {
ArrayList<String> transportModes = new ArrayList<String>();
transportModes.add(TransportMode.BUS);
transportModes.add(TransportMode.METRO);
transportModes.add(TransportMode.TRAIN);
transportModes.add(TransportMode.TRAM);
transportModes.add(TransportMode.WAX);
do {
JourneyQuery journeyQuery = new JourneyQuery.Builder()
.transportModes(transportModes)
.origin(
cursor.getString(FavoritesDbAdapter.INDEX_START_POINT),
cursor.getInt(FavoritesDbAdapter.INDEX_START_POINT_LATITUDE),
cursor.getInt(FavoritesDbAdapter.INDEX_START_POINT_LONGITUDE))
.destination(
cursor.getString(FavoritesDbAdapter.INDEX_END_POINT),
cursor.getInt(FavoritesDbAdapter.INDEX_END_POINT_LATITUDE),
cursor.getInt(FavoritesDbAdapter.INDEX_END_POINT_LONGITUDE))
.create();
// Store new journey
String json = null;
try {
json = journeyQuery.toJson(false).toString();
} catch (JSONException e) {
Log.e(TAG, "Failed to convert journey to a json document.");
}
// Malformed json, skip it.
if (json != null) {
ContentValues values = new ContentValues();
values.put(Journeys.JOURNEY_DATA, json);
values.put(Journeys.STARRED, "1");
values.put(Journeys.CREATED_AT,
cursor.getString(FavoritesDbAdapter.INDEX_CREATED));
getContentResolver().insert(Journeys.CONTENT_URI, values);
Log.d(TAG, String.format("Converted favorite journey %s -> %s.",
journeyQuery.origin.getName(), journeyQuery.destination.getName()));
}
} while (cursor.moveToNext());
}
cursor.close();
favoritesDbAdapter.close();
}
private static boolean isFavoritesMigrated(Context context) {
SharedPreferences settings = context.getSharedPreferences("sthlmtraveling", MODE_PRIVATE);
boolean migrated =
settings.getBoolean("converted_favorites", false);
if (migrated) {
Log.d(TAG, "Favorites converted.");
return true;
}
FavoritesDbAdapter favoritesDbAdapter = null;
try {
favoritesDbAdapter = new FavoritesDbAdapter(context);
favoritesDbAdapter.open();
Cursor favoritesCursor = favoritesDbAdapter.fetch();
if (favoritesCursor.getCount() == 0) {
// Also mark it as migrated to avoid sending an intent.
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("converted_favorites", true);
editor.apply();
migrated = true;
}
} finally {
if (favoritesDbAdapter != null) {
favoritesDbAdapter.close();
}
}
if (migrated) {
Log.d(TAG, "No previous favorites, treat as converted.");
return true;
}
String[] projection = new String[]{
Journeys._ID, // 0
};
ContentResolver resolver = context.getContentResolver();
Cursor journeyCursor = resolver.query(Journeys.CONTENT_URI, projection, null, null, null);
if (journeyCursor.getCount() > 0) {
journeyCursor.close();
// Also mark it as migrated to avoid sending an intent.
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("converted_favorites", true);
editor.apply();
Log.d(TAG, "Existing journeys, treat as converted.");
return true;
}
journeyCursor.close();
return false;
}
public static boolean hasMigrations(Context context) {
boolean hasMigrations = false;
try {
hasMigrations = !isFavoritesMigrated(context);
} catch (Exception e) {
Log.w(TAG, "Failed to determine if we had any migrations. Skip and move on.");
}
return hasMigrations;
}
public static void startService(Context context) {
if (hasMigrations(context)) {
WakefulIntentService.acquireStaticLock(context);
context.startService(new Intent(context, DataMigrationService.class));
}
}
}