package com.github.andlyticsproject;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.github.andlyticsproject.db.AndlyticsDb;
import com.github.andlyticsproject.db.DeveloperAccountsTable;
import com.github.andlyticsproject.model.DeveloperAccount;
public class DeveloperAccountManager {
private static final String TAG = DeveloperAccountManager.class.getSimpleName();
private static DeveloperAccountManager instance;
private AndlyticsDb andlyticsDb;
public static synchronized DeveloperAccountManager getInstance(Context context) {
if (instance == null) {
instance = new DeveloperAccountManager(context);
}
return instance;
}
private DeveloperAccountManager(Context context) {
andlyticsDb = AndlyticsDb.getInstance(context);
}
public synchronized long addDeveloperAccount(DeveloperAccount account) {
return andlyticsDb.addDeveloperAccount(account);
}
public synchronized long addOrUpdateDeveloperAccount(DeveloperAccount account) {
if (account.getId() != null) {
updateDeveloperAccount(account);
return account.getId();
}
long id = andlyticsDb.addDeveloperAccount(account);
account.setId(id);
return id;
}
public List<DeveloperAccount> getAllDeveloperAccounts() {
List<DeveloperAccount> result = new ArrayList<DeveloperAccount>();
SQLiteDatabase db = andlyticsDb.getReadableDatabase();
Cursor c = null;
try {
c = db.query(DeveloperAccountsTable.DATABASE_TABLE_NAME,
DeveloperAccountsTable.ALL_COLUMNS, null, null, null, null, "_id asc", null);
while (c.moveToNext()) {
DeveloperAccount account = createAcount(c);
result.add(account);
}
return result;
} finally {
if (c != null) {
c.close();
}
}
}
public List<DeveloperAccount> getActiveDeveloperAccounts() {
List<DeveloperAccount> result = new ArrayList<DeveloperAccount>();
SQLiteDatabase db = andlyticsDb.getReadableDatabase();
Cursor c = null;
try {
c = db.query(DeveloperAccountsTable.DATABASE_TABLE_NAME,
DeveloperAccountsTable.ALL_COLUMNS, "state = ? or state = ?",
new String[] { Integer.toString(DeveloperAccount.State.ACTIVE.ordinal()),
Integer.toString(DeveloperAccount.State.SELECTED.ordinal()) }, null,
null, "_id asc", null);
while (c.moveToNext()) {
DeveloperAccount account = createAcount(c);
result.add(account);
}
return result;
} finally {
if (c != null) {
c.close();
}
}
}
public List<DeveloperAccount> getHiddenDeveloperAccounts() {
return getDeveloperAccountsByState(DeveloperAccount.State.HIDDEN);
}
public DeveloperAccount getSelectedDeveloperAccount() {
List<DeveloperAccount> accounts = getDeveloperAccountsByState(DeveloperAccount.State.SELECTED);
if (accounts.isEmpty()) {
return null;
}
if (accounts.size() > 1) {
throw new IllegalStateException("More than one selected developer account: " + accounts);
}
return accounts.get(0);
}
public List<DeveloperAccount> getDeveloperAccountsByState(DeveloperAccount.State state) {
List<DeveloperAccount> result = new ArrayList<DeveloperAccount>();
SQLiteDatabase db = andlyticsDb.getReadableDatabase();
Cursor c = null;
try {
c = db.query(DeveloperAccountsTable.DATABASE_TABLE_NAME,
DeveloperAccountsTable.ALL_COLUMNS, "state = ?",
new String[] { Integer.toString(state.ordinal()) }, null, null, "_id asc", null);
while (c.moveToNext()) {
DeveloperAccount account = createAcount(c);
result.add(account);
}
return result;
} finally {
if (c != null) {
c.close();
}
}
}
public DeveloperAccount findDeveloperAccountById(long id) {
SQLiteDatabase db = andlyticsDb.getReadableDatabase();
Cursor c = null;
try {
c = db.query(DeveloperAccountsTable.DATABASE_TABLE_NAME,
DeveloperAccountsTable.ALL_COLUMNS, "_id = ?",
new String[] { Long.toString(id) }, null, null, "_id asc", null);
if (!c.moveToNext()) {
return null;
}
return createAcount(c);
} finally {
if (c != null) {
c.close();
}
}
}
public DeveloperAccount findDeveloperAccountByName(String name) {
SQLiteDatabase db = andlyticsDb.getReadableDatabase();
Cursor c = null;
try {
c = db.query(DeveloperAccountsTable.DATABASE_TABLE_NAME,
DeveloperAccountsTable.ALL_COLUMNS, "name = ?", new String[] { name }, null,
null, "_id asc", null);
if (!c.moveToNext()) {
return null;
}
return createAcount(c);
} finally {
if (c != null) {
c.close();
}
}
}
public synchronized void updateDeveloperAccount(DeveloperAccount account) {
SQLiteDatabase db = andlyticsDb.getWritableDatabase();
ContentValues values = AndlyticsDb.toValues(account);
values.put(DeveloperAccountsTable.ROWID, account.getId());
db.update(DeveloperAccountsTable.DATABASE_TABLE_NAME, values, "_id = ?",
new String[] { Long.toString(account.getId()) });
}
public synchronized void deleteDeveloperAccount(DeveloperAccount account) {
SQLiteDatabase db = andlyticsDb.getWritableDatabase();
db.delete(DeveloperAccountsTable.DATABASE_TABLE_NAME, "name = ?",
new String[] { account.getName() });
}
public synchronized void selectDeveloperAccount(String name) {
SQLiteDatabase db = andlyticsDb.getWritableDatabase();
db.beginTransaction();
try {
List<DeveloperAccount> currentlySelected = getDeveloperAccountsByState(DeveloperAccount.State.SELECTED);
if (currentlySelected.size() > 1) {
throw new IllegalStateException("More than one selected account: "
+ currentlySelected);
}
if (!currentlySelected.isEmpty()) {
DeveloperAccount selected = currentlySelected.get(0);
if (selected.getName().equals(name)) {
return;
}
selected.deselect();
updateDeveloperAccount(selected);
Log.d(TAG, "Set to ACTIVE: " + selected);
}
DeveloperAccount toSelect = findDeveloperAccountByName(name);
if (toSelect == null) {
throw new IllegalStateException("Account not found: " + name);
}
toSelect.select();
updateDeveloperAccount(toSelect);
Log.d(TAG, "Set to SELECTED: " + toSelect);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
public synchronized void unselectDeveloperAccount() {
SQLiteDatabase db = andlyticsDb.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DeveloperAccountsTable.STATE, DeveloperAccount.State.ACTIVE.ordinal());
db.update(DeveloperAccountsTable.DATABASE_TABLE_NAME, values, DeveloperAccountsTable.STATE
+ " = ?",
new String[] { Integer.toString(DeveloperAccount.State.SELECTED.ordinal()) });
}
public synchronized void activateDeveloperAccount(String accountName) {
setAccountState(accountName, DeveloperAccount.State.ACTIVE);
}
public synchronized void hideDeveloperAccount(String accountName) {
setAccountState(accountName, DeveloperAccount.State.HIDDEN);
}
private void setAccountState(String accountName, DeveloperAccount.State state) {
SQLiteDatabase db = andlyticsDb.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DeveloperAccountsTable.STATE, state.ordinal());
db.update(DeveloperAccountsTable.DATABASE_TABLE_NAME, values, DeveloperAccountsTable.NAME
+ " = ?", new String[] { accountName });
}
private DeveloperAccount createAcount(Cursor c) {
long id = c.getLong(c.getColumnIndex(DeveloperAccountsTable.ROWID));
String name = c.getString(c.getColumnIndex(DeveloperAccountsTable.NAME));
DeveloperAccount.State currentState = DeveloperAccount.State.values()[c.getInt(c
.getColumnIndex(DeveloperAccountsTable.STATE))];
Date lastStatsUpdate = new Date(c.getLong(c
.getColumnIndex(DeveloperAccountsTable.LAST_STATS_UPDATE)));
DeveloperAccount account = new DeveloperAccount(name, currentState);
account.setId(id);
account.setLastStatsUpdate(lastStatsUpdate);
return account;
}
public long getLastStatsRemoteUpdateTime(String accountName) {
DeveloperAccount account = findDeveloperAccountByName(accountName);
if (account == null) {
throw new IllegalStateException("Account not found: " + accountName);
}
return account.getLastStatsUpdate().getTime();
}
public synchronized void saveLastStatsRemoteUpdateTime(String accountName, long timestamp) {
DeveloperAccount account = findDeveloperAccountByName(accountName);
if (account == null) {
throw new IllegalStateException("Account not found: " + accountName);
}
account.setLastStatsUpdate(new Date(timestamp));
updateDeveloperAccount(account);
}
}