package co.smartreceipts.android.sync;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import com.google.common.base.Preconditions;
import java.io.File;
import java.sql.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.inject.Inject;
import co.smartreceipts.android.di.scopes.ApplicationScope;
import co.smartreceipts.android.sync.errors.CriticalSyncError;
import co.smartreceipts.android.sync.errors.SyncErrorType;
import co.smartreceipts.android.sync.model.RemoteBackupMetadata;
import co.smartreceipts.android.sync.model.impl.Identifier;
import co.smartreceipts.android.sync.network.NetworkManager;
import co.smartreceipts.android.sync.network.SupportedNetworkType;
import co.smartreceipts.android.sync.provider.SyncProvider;
import co.smartreceipts.android.sync.provider.SyncProviderFactory;
import co.smartreceipts.android.sync.provider.SyncProviderStore;
import io.reactivex.Observable;
import io.reactivex.Single;
/**
* A global manager for whatever our current backup provider may (or may not) be
*/
@ApplicationScope
public class BackupProvidersManager implements BackupProvider {
private final SyncProviderFactory syncProviderFactory;
private final SyncProviderStore syncProviderStore;
private final NetworkManager networkManager;
private final Set<BackupProviderChangeListener> backupProviderChangeListeners = new CopyOnWriteArraySet<>();
private BackupProvider backupProvider;
@Inject
public BackupProvidersManager(SyncProviderFactory syncProviderFactory, SyncProviderStore syncProviderStore,
NetworkManager networkManager) {
this.syncProviderFactory = syncProviderFactory;
this.syncProviderStore = syncProviderStore;
this.networkManager = networkManager;
backupProvider = syncProviderFactory.get(this.syncProviderStore.getProvider());
}
public void registerChangeListener(@NonNull BackupProviderChangeListener backupProviderChangeListener) {
Preconditions.checkNotNull(backupProviderChangeListener);
backupProviderChangeListeners.add(backupProviderChangeListener);
}
public void unregisterChangeListener(@NonNull BackupProviderChangeListener backupProviderChangeListener) {
Preconditions.checkNotNull(backupProviderChangeListener);
backupProviderChangeListeners.remove(backupProviderChangeListener);
}
public synchronized void setAndInitializeSyncProvider(@NonNull SyncProvider syncProvider, @Nullable FragmentActivity fragmentActivity) {
if (syncProviderStore.setSyncProvider(syncProvider)) {
backupProvider.deinitialize();
backupProvider = syncProviderFactory.get(syncProvider);
backupProvider.initialize(fragmentActivity);
for (final BackupProviderChangeListener backupProviderChangeListener : backupProviderChangeListeners) {
backupProviderChangeListener.onProviderChanged(syncProvider);
}
}
}
public synchronized void setAndInitializeNetworkProviderType(@NonNull SupportedNetworkType supportedNetworkType) {
networkManager.setAndInitializeNetworkProviderType(supportedNetworkType);
}
@NonNull
public SyncProvider getSyncProvider() {
return syncProviderStore.getProvider();
}
@Override
public synchronized void initialize(@Nullable FragmentActivity activity) {
backupProvider.initialize(activity);
}
@Override
public synchronized void deinitialize() {
backupProvider.deinitialize();
}
@Override
public synchronized boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
return backupProvider.onActivityResult(requestCode, resultCode, data);
}
@NonNull
@Override
public Single<List<RemoteBackupMetadata>> getRemoteBackups() {
return backupProvider.getRemoteBackups();
}
@Nullable
@Override
public Identifier getDeviceSyncId() {
return backupProvider.getDeviceSyncId();
}
@NonNull
@Override
public Date getLastDatabaseSyncTime() {
return backupProvider.getLastDatabaseSyncTime();
}
@NonNull
@Override
public Single<Boolean> restoreBackup(@NonNull RemoteBackupMetadata remoteBackupMetadata, boolean overwriteExistingData) {
return backupProvider.restoreBackup(remoteBackupMetadata, overwriteExistingData);
}
@NonNull
@Override
public Single<Boolean> deleteBackup(@NonNull RemoteBackupMetadata remoteBackupMetadata) {
return backupProvider.deleteBackup(remoteBackupMetadata);
}
@Override
public Single<Boolean> clearCurrentBackupConfiguration() {
return backupProvider.clearCurrentBackupConfiguration();
}
@NonNull
@Override
public Single<List<File>> downloadAllData(@NonNull RemoteBackupMetadata remoteBackupMetadata, @NonNull File downloadLocation) {
return backupProvider.downloadAllData(remoteBackupMetadata, downloadLocation);
}
@NonNull
@Override
public Single<List<File>> debugDownloadAllData(@NonNull RemoteBackupMetadata remoteBackupMetadata, @NonNull File downloadLocation) {
return backupProvider.debugDownloadAllData(remoteBackupMetadata, downloadLocation);
}
@NonNull
@Override
public Observable<CriticalSyncError> getCriticalSyncErrorStream() {
return backupProvider.getCriticalSyncErrorStream();
}
@Override
public void markErrorResolved(@NonNull SyncErrorType syncErrorType) {
backupProvider.markErrorResolved(syncErrorType);
}
}