namespace uniflash.preferences {
	'use strict';

	//auto save and always read from file upon access. 
	export class Preferences {

		private preferencesMap = {};
		private filePath = 'preferences.json';
		private lastOpPromise = null;
		private recentSessionsId = 'recent-session-files';

		static $inject = ['$window', '$q', '$log', 'ticFileStorage', 'ticFileFactory'];

		constructor(private $window, private $q, private $log, private ticFileStorage, private ticFileFactory) {
			this.ticFileStorage.getAppDataDirectory()
				.then((parentPath) => {
					this.filePath = parentPath + '/' + this.filePath;
					this.load();
				});
			this.lastOpPromise = this.load();
			this.$window.onbeforeunload = this.load();
		}

		load() {
			return this.ticFileStorage.fileExists(this.filePath)
				.then((isExists) => {
					if (isExists) {
						return this.ticFileStorage.openFile(this.filePath)//text
							.then((data) => {
								this.preferencesMap = JSON.parse(data);
								return this.getRecentSessions();
							})
							.catch((err) => {
								this.$log.error('Preferences get err: ' + err + ', using default.');
							});
					} else {
						this.preferencesMap = this.getDefault();
					}
				});
		}

		get(id) {
			return this.preferencesMap[id];
		}

		set(id: string, val) {
			this.preferencesMap[id] = val;
			return this.lastOpPromise
				.then(() => {
					this.lastOpPromise = this.ticFileStorage.saveFile(this.filePath, JSON.stringify(this.preferencesMap), ti_common.file.ContentType.Text);
					return this.lastOpPromise;
				});
		}

		getDefault() {
			return {
				'Auto Disconnect': true,
				'runTargetAfterProgramLoad': true,
				'runTargetAfterProgramLoadC2000': false,
				'showDetectWelcomePage': true,
			};
		}

		purgeRecentSessions() {
			return this.set(this.recentSessionsId, []);
		}

		pushRecentSessionFile(file: ti_common.file.File) {
			let isDuplicate = false;
			let listOfSessions;
			return this.getRecentSessions()
				.then((list) => {
					listOfSessions = list;
					return angular.forEach(listOfSessions, (sessionFile) => {
						if (sessionFile.path === file.path) {
							isDuplicate = true;
						}
					});
				})
				.then(() => {
					if (isDuplicate) {
						return;
					}

					if (listOfSessions.length > 5) {
						listOfSessions.shift();
					}

					listOfSessions.push(file.toJSON());
					return this.set(this.recentSessionsId, listOfSessions);
				});
		}

		getRecentSessions() {
			let listOfSessions = this.get(this.recentSessionsId);
			let listOfExistingSessions = [];
			let promiseList = [];
			//only keep the files that still exist
			angular.forEach(listOfSessions, (sessionFileJson) => {
				promiseList.push(this.ticFileStorage.fileExists(sessionFileJson.path)
					.then((isExists) => {
						if (isExists) {
							return this.ticFileFactory.createFromJSON(sessionFileJson);
						}
					})
					.then((file) => {
						if (file) {
							listOfExistingSessions.push(file);
						}
					}));
			});

			return this.$q.all(promiseList)
				.then(() => {
					return listOfExistingSessions;
				});
		}
	};

	angular.module('uniflash').service('ufPreferencesSrv', Preferences);
}