From 946ad7c71a1a47acd331e48d94136c19a8a7e722 Mon Sep 17 00:00:00 2001
From: Laurent Cozic <laurent@cozic.net>
Date: Fri, 24 Nov 2017 18:06:30 +0000
Subject: [PATCH] All: Started moving sync target logic under SyncTarget
 classes

---
 CliClient/app/app.js                          |  4 +-
 CliClient/app/command-sync.js                 |  2 +-
 ElectronClient/app/app.js                     |  2 +-
 .../app/gui/OneDriveLoginScreen.jsx           |  6 +-
 ReactNativeClient/lib/SyncTarget3.js          | 28 +++----
 .../lib/components/screens/onedrive-login.js  |  6 +-
 .../lib/components/shared/side-menu-shared.js |  4 +-
 ReactNativeClient/lib/models/setting.js       |  1 -
 ReactNativeClient/lib/registry.js             | 84 +++++++++----------
 ReactNativeClient/root.js                     |  4 +-
 10 files changed, 68 insertions(+), 73 deletions(-)

diff --git a/CliClient/app/app.js b/CliClient/app/app.js
index 99f0c71b42..f2863c49e8 100644
--- a/CliClient/app/app.js
+++ b/CliClient/app/app.js
@@ -168,9 +168,9 @@ class Application extends BaseApplication {
 			await doExit();
 		}, 5000);
 
-		if (await reg.syncStarted()) {
+		if (await reg.syncTarget().syncStarted()) {
 			this.stdout(_('Cancelling background synchronisation... Please wait.'));
-			const sync = await reg.synchronizer(Setting.value('sync.target'));
+			const sync = await reg.syncTarget().synchronizer();
 			await sync.cancel();
 		}
 
diff --git a/CliClient/app/command-sync.js b/CliClient/app/command-sync.js
index ae96d7ca78..f07e0da7e0 100644
--- a/CliClient/app/command-sync.js
+++ b/CliClient/app/command-sync.js
@@ -64,7 +64,7 @@ class Command extends BaseCommand {
 
 	async doAuth(syncTargetId) {
 		const syncTarget = reg.syncTarget(this.syncTargetId_);
-		this.oneDriveApiUtils_ = new OneDriveApiNodeUtils(syncTarget.oneDriveApi());
+		this.oneDriveApiUtils_ = new OneDriveApiNodeUtils(syncTarget.api());
 		const auth = await this.oneDriveApiUtils_.oauthDance({
 			log: (...s) => { return this.stdout(...s); }
 		});
diff --git a/ElectronClient/app/app.js b/ElectronClient/app/app.js
index 8252aecdb3..d2bbc15232 100644
--- a/ElectronClient/app/app.js
+++ b/ElectronClient/app/app.js
@@ -132,7 +132,7 @@ class Application extends BaseApplication {
 		}
 
 		if (['NOTE_UPDATE_ONE', 'NOTE_DELETE', 'FOLDER_UPDATE_ONE', 'FOLDER_DELETE'].indexOf(action.type) >= 0) {
-			if (!await reg.syncStarted()) reg.scheduleSync();
+			if (!await reg.syncTarget().syncStarted()) reg.scheduleSync();
 		}
 
 		const result = await super.generalMiddleware(store, next, action);
diff --git a/ElectronClient/app/gui/OneDriveLoginScreen.jsx b/ElectronClient/app/gui/OneDriveLoginScreen.jsx
index 5062fb6bdc..3c7a84be97 100644
--- a/ElectronClient/app/gui/OneDriveLoginScreen.jsx
+++ b/ElectronClient/app/gui/OneDriveLoginScreen.jsx
@@ -47,7 +47,7 @@ class OneDriveLoginScreenComponent extends React.Component {
 			this.authCode_ = code[1];
 
 			try {
-				await reg.oneDriveApi().execTokenRequest(this.authCode_, this.redirectUrl(), true);
+				await reg.syncTarget().api().execTokenRequest(this.authCode_, this.redirectUrl(), true);
 				this.props.dispatch({ type: 'NAV_BACK' });
 				reg.scheduleSync(0);
 			} catch (error) {
@@ -62,11 +62,11 @@ class OneDriveLoginScreenComponent extends React.Component {
 	}
 
 	startUrl() {
-		return reg.oneDriveApi().authCodeUrl(this.redirectUrl());
+		return reg.syncTarget().api().authCodeUrl(this.redirectUrl());
 	}
 
 	redirectUrl() {
-		return reg.oneDriveApi().nativeClientRedirectUrl();
+		return reg.syncTarget().api().nativeClientRedirectUrl();
 	}
 
 	render() {
diff --git a/ReactNativeClient/lib/SyncTarget3.js b/ReactNativeClient/lib/SyncTarget3.js
index 2cfcf29139..9e76dcd298 100644
--- a/ReactNativeClient/lib/SyncTarget3.js
+++ b/ReactNativeClient/lib/SyncTarget3.js
@@ -11,7 +11,7 @@ class SyncTarget3 extends BaseSyncTarget {
 
 	constructor(db) {
 		super();
-		this.oneDriveApi_ = null;
+		this.api_ = null;
 	}
 
 	id() {
@@ -27,18 +27,18 @@ class SyncTarget3 extends BaseSyncTarget {
 	}
 
 	isAuthenticated() {
-		return this.oneDriveApi_ && this.oneDriveApi_.auth();
+		return this.api().auth();
 	}
 
-	oneDriveApi() {
-		if (this.oneDriveApi_) return this.oneDriveApi_;
+	api() {
+		if (this.api_) return this.api_;
 
 		const isPublic = Setting.value('appType') != 'cli';
 
-		this.oneDriveApi_ = new OneDriveApi(parameters().oneDrive.id, parameters().oneDrive.secret, isPublic);
-		this.oneDriveApi_.setLogger(this.logger());
+		this.api_ = new OneDriveApi(parameters().oneDrive.id, parameters().oneDrive.secret, isPublic);
+		this.api_.setLogger(this.logger());
 
-		this.oneDriveApi_.on('authRefreshed', (a) => {
+		this.api_.on('authRefreshed', (a) => {
 			this.logger().info('Saving updated OneDrive auth.');
 			Setting.setValue('sync.' + this.id() + '.auth', a ? JSON.stringify(a) : null);
 		});
@@ -53,28 +53,24 @@ class SyncTarget3 extends BaseSyncTarget {
 				auth = null;
 			}
 
-			this.oneDriveApi_.setAuth(auth);
+			this.api_.setAuth(auth);
 		}
 		
-		return this.oneDriveApi_;
+		return this.api_;
 	}
 
 	async initSynchronizer() {
 		let fileApi = null;
 
-		if (!this.oneDriveApi().auth()) throw new Error('User is not authentified');
-		const appDir = await this.oneDriveApi().appDirectory();
-		fileApi = new FileApi(appDir, new FileApiDriverOneDrive(this.oneDriveApi()));
+		if (!this.api().auth()) throw new Error('User is not authentified');
+		const appDir = await this.api().appDirectory();
+		fileApi = new FileApi(appDir, new FileApiDriverOneDrive(this.api()));
 		fileApi.setSyncTargetId(this.id());
 		fileApi.setLogger(this.logger());
 
 		return new Synchronizer(this.db(), fileApi, Setting.value('appType'));
 	}
 
-	isAuthenticated() {
-		return true;
-	}
-
 }
 
 module.exports = SyncTarget3;
\ No newline at end of file
diff --git a/ReactNativeClient/lib/components/screens/onedrive-login.js b/ReactNativeClient/lib/components/screens/onedrive-login.js
index 30653bf9b9..c47175ced8 100644
--- a/ReactNativeClient/lib/components/screens/onedrive-login.js
+++ b/ReactNativeClient/lib/components/screens/onedrive-login.js
@@ -28,11 +28,11 @@ class OneDriveLoginScreenComponent extends BaseScreenComponent {
 	}
 
 	startUrl() {
-		return reg.oneDriveApi().authCodeUrl(this.redirectUrl());
+		return reg.syncTarget().api().authCodeUrl(this.redirectUrl());
 	}
 
 	redirectUrl() {
-		return reg.oneDriveApi().nativeClientRedirectUrl();
+		return reg.syncTarget().api().nativeClientRedirectUrl();
 	}
 
 	async webview_load(noIdeaWhatThisIs) {
@@ -48,7 +48,7 @@ class OneDriveLoginScreenComponent extends BaseScreenComponent {
 			this.authCode_ = code[1];
 
 			try {
-				await reg.oneDriveApi().execTokenRequest(this.authCode_, this.redirectUrl(), true);
+				await reg.syncTarget().api().execTokenRequest(this.authCode_, this.redirectUrl(), true);
 				this.props.dispatch({ type: 'NAV_BACK' });
 				reg.scheduleSync(0);
 			} catch (error) {
diff --git a/ReactNativeClient/lib/components/shared/side-menu-shared.js b/ReactNativeClient/lib/components/shared/side-menu-shared.js
index 8c434eefa5..3accd3533e 100644
--- a/ReactNativeClient/lib/components/shared/side-menu-shared.js
+++ b/ReactNativeClient/lib/components/shared/side-menu-shared.js
@@ -36,7 +36,7 @@ shared.synchronize_press = async function(comp) {
 
 	const action = comp.props.syncStarted ? 'cancel' : 'start';
 
-	if (Setting.value('sync.target') == Setting.SYNC_TARGET_ONEDRIVE && !reg.oneDriveApi().auth()) {		
+	if (!reg.syncTarget().isAuthenticated()) {		
 		comp.props.dispatch({
 			type: 'NAV_GO',
 			routeName: 'OneDriveLogin',
@@ -46,7 +46,7 @@ shared.synchronize_press = async function(comp) {
 
 	let sync = null;
 	try {
-		sync = await reg.synchronizer(Setting.value('sync.target'))
+		sync = await reg.syncTarget().synchronizer();
 	} catch (error) {
 		reg.logger().info('Could not acquire synchroniser:');
 		reg.logger().info(error);
diff --git a/ReactNativeClient/lib/models/setting.js b/ReactNativeClient/lib/models/setting.js
index 40880b1bb8..bcd2afc8fa 100644
--- a/ReactNativeClient/lib/models/setting.js
+++ b/ReactNativeClient/lib/models/setting.js
@@ -32,7 +32,6 @@ class Setting extends BaseModel {
 				if (!this.metadata_.hasOwnProperty(n)) continue;
 				this.keys_.push(n);
 			}
-			//this.keys_.sort();
 		}
 
 		if (appType || publicOnly) {
diff --git a/ReactNativeClient/lib/registry.js b/ReactNativeClient/lib/registry.js
index f6716911fd..4cab15e2d3 100644
--- a/ReactNativeClient/lib/registry.js
+++ b/ReactNativeClient/lib/registry.js
@@ -4,8 +4,6 @@ const { parameters } = require('lib/parameters.js');
 const { FileApi } = require('lib/file-api.js');
 const { Database } = require('lib/database.js');
 const { Synchronizer } = require('lib/synchronizer.js');
-const SyncTarget1 = require('lib/SyncTarget1.js');
-const SyncTarget3 = require('lib/SyncTarget3.js');
 const { FileApiDriverOneDrive } = require('lib/file-api-driver-onedrive.js');
 const { shim } = require('lib/shim.js');
 const { time } = require('lib/time-utils.js');
@@ -16,12 +14,12 @@ const reg = {};
 
 reg.initSynchronizerStates_ = {};
 reg.syncTargetClasses_ = {
-	1: SyncTarget1,
-	// 2: SyncTarget2,
-	3: SyncTarget3,
+	1: require('lib/SyncTarget1.js'),
+	// 2: require('lib/SyncTarget2.js'),
+	3: require('lib/SyncTarget3.js'),
 };
 reg.syncTargets_ = {};
-reg.synchronizers_ = {};
+//reg.synchronizers_ = {};
 
 reg.logger = () => {
 	if (!reg.logger_) {
@@ -49,42 +47,42 @@ reg.syncTarget = (syncTargetId = null) => {
 	return target;
 }
 
-reg.synchronizer = async (syncTargetId) => {
-	if (reg.synchronizers_[syncTargetId]) return reg.synchronizers_[syncTargetId];
-	if (!reg.db()) throw new Error('Cannot initialize synchronizer: db not initialized');
+// reg.synchronizer = async (syncTargetId) => {
+// 	if (reg.synchronizers_[syncTargetId]) return reg.synchronizers_[syncTargetId];
+// 	if (!reg.db()) throw new Error('Cannot initialize synchronizer: db not initialized');
 
-	if (reg.initSynchronizerStates_[syncTargetId] == 'started') {
-		// Synchronizer is already being initialized, so wait here till it's done.
-		return new Promise((resolve, reject) => {
-			const iid = setInterval(() => {
-				if (reg.initSynchronizerStates_[syncTargetId] == 'ready') {
-					clearInterval(iid);
-					resolve(reg.synchronizers_[syncTargetId]);
-				}
-				if (reg.initSynchronizerStates_[syncTargetId] == 'error') {
-					clearInterval(iid);
-					reject(new Error('Could not initialise synchroniser'));
-				}
-			}, 1000);
-		});
-	} else {
-		reg.initSynchronizerStates_[syncTargetId] = 'started';
+// 	if (reg.initSynchronizerStates_[syncTargetId] == 'started') {
+// 		// Synchronizer is already being initialized, so wait here till it's done.
+// 		return new Promise((resolve, reject) => {
+// 			const iid = setInterval(() => {
+// 				if (reg.initSynchronizerStates_[syncTargetId] == 'ready') {
+// 					clearInterval(iid);
+// 					resolve(reg.synchronizers_[syncTargetId]);
+// 				}
+// 				if (reg.initSynchronizerStates_[syncTargetId] == 'error') {
+// 					clearInterval(iid);
+// 					reject(new Error('Could not initialise synchroniser'));
+// 				}
+// 			}, 1000);
+// 		});
+// 	} else {
+// 		reg.initSynchronizerStates_[syncTargetId] = 'started';
 
-		try {
-			const sync = await reg.initSynchronizer_(syncTargetId);
-			reg.synchronizers_[syncTargetId] = sync;
-			reg.initSynchronizerStates_[syncTargetId] = 'ready';
-			return sync;
-		} catch (error) {
-			reg.initSynchronizerStates_[syncTargetId] = 'error';
-			throw error;
-		}
-	}
-}
+// 		try {
+// 			const sync = await reg.initSynchronizer_(syncTargetId);
+// 			reg.synchronizers_[syncTargetId] = sync;
+// 			reg.initSynchronizerStates_[syncTargetId] = 'ready';
+// 			return sync;
+// 		} catch (error) {
+// 			reg.initSynchronizerStates_[syncTargetId] = 'error';
+// 			throw error;
+// 		}
+// 	}
+// }
 
-reg.syncHasAuth = (syncTargetId) => {
-	return reg.syncTargets(syncTargetId).isAuthenticated();
-}
+// reg.syncHasAuth = (syncTargetId) => {
+// 	return reg.syncTarget(syncTargetId).isAuthenticated();
+// }
 
 reg.scheduleSync = async (delay = null) => {
 	if (delay === null) delay = 1000 * 3;
@@ -107,7 +105,7 @@ reg.scheduleSync = async (delay = null) => {
 
 		const syncTargetId = Setting.value('sync.target');
 
-		if (!reg.syncHasAuth(syncTargetId)) {
+		if (!reg.syncTarget(syncTargetId).isAuthenticated()) {
 			reg.logger().info('Synchroniser is missing credentials - manual sync required to authenticate.');
 			return;
 		}
@@ -143,9 +141,9 @@ reg.scheduleSync = async (delay = null) => {
 	}
 }
 
-reg.syncStarted = async () => {
-	return reg.syncTarget().syncStarted();
-}
+// reg.syncStarted = async () => {
+// 	return reg.syncTarget().syncStarted();
+// }
 
 reg.setupRecurrentSync = () => {
 	if (reg.recurrentSyncId_) {
diff --git a/ReactNativeClient/root.js b/ReactNativeClient/root.js
index 9ef107549c..c67705682f 100644
--- a/ReactNativeClient/root.js
+++ b/ReactNativeClient/root.js
@@ -9,6 +9,7 @@ const { AppNav } = require('lib/components/app-nav.js');
 const { Logger } = require('lib/logger.js');
 const { Note } = require('lib/models/note.js');
 const { Folder } = require('lib/models/folder.js');
+const BaseSyncTarget = require('lib/BaseSyncTarget.js');
 const { FoldersScreenUtils } = require('lib/folders-screen-utils.js');
 const { Resource } = require('lib/models/resource.js');
 const { Tag } = require('lib/models/tag.js');
@@ -47,7 +48,7 @@ const generalMiddleware = store => next => async (action) => {
 	if (action.type == 'NAV_GO') Keyboard.dismiss();
 
 	if (['NOTE_UPDATE_ONE', 'NOTE_DELETE', 'FOLDER_UPDATE_ONE', 'FOLDER_DELETE'].indexOf(action.type) >= 0) {
-		if (!await reg.syncStarted()) reg.scheduleSync();
+		if (!await reg.syncTarget().syncStarted()) reg.scheduleSync();
 	}
 
 	if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'sync.interval' || action.type == 'SETTING_UPDATE_ALL') {
@@ -273,6 +274,7 @@ async function initialize(dispatch, backButtonHandler) {
 	reg.dispatch = dispatch;
 	BaseModel.dispatch = dispatch;
 	FoldersScreenUtils.dispatch = dispatch;
+	BaseSyncTarget.dispatch = dispatch;
 	BaseModel.db_ = db;
 
 	BaseItem.loadClass('Note', Note);