Integrity = {};

Integrity.userData = null;
Integrity.Tests = {
	data: [],
	forbiddenTags: ['and', 'or', 'not'],
	convertCallback: function(data, doNotSave) {
		var root = 'tests';
		var result = {};

		if (data && data[root] instanceof Array) {
			if (!doNotSave) {
				Integrity.Tests.data = $.extend(true, [], data[root]);
			}
			result = createGenericData4Grid(data[root]);

			for (var ii = 0; ii < result.rows.length; ii++) {
				Integrity.Tests.extendRow(result.rows[ii]);
			}
		}

		return result;
	},
	extendRow: function(row) {
		if (typeof row === "object") {
			if (row.tags) {
				var md = row.tags.match(/testType_(\w+)/);
				row.type = md ? L("app.crudTest.testType." + md[1]) : "";
				
				row.platform = [
					'<span class="', (row.tags.indexOf('platform_android') >= 0 ? 'has' : 'hasno'), '">[A]</span>',
					'<span class="', (row.tags.indexOf('platform_ios') >= 0 ? 'has' : 'hasno'), '">[I]</span>',
					'<span class="', (row.tags.indexOf('platform_bb') >= 0 ? 'has' : 'hasno'), '">[B]</span>'
						].join('');
			} else {
				row.type = '';
				row.platform = '';
			}


			return row;
		} else {
			return {};
		}
	},
	extendArray: function(aTests) {
		if (aTests instanceof Array) {
			for (var ii = aTests.length - 1; ii >= 0; ii--) {
				Integrity.Tests.extendRow(aTests[ii]);
			}

			return aTests;
		} else {
			return [];
		}
	},
	getTestById: function(id) {
		id = parseInt(id);
		for (var ii = Integrity.Tests.data.length - 1; ii >= 0; ii--) {
			var tt = Integrity.Tests.data[ii];
			if (parseInt(tt.testId) === id) {
				return tt;
			}
		}
	},
	getStepFromTest: function(testId, stepId) {
		stepId = parseInt(stepId);
		var testObject = Integrity.Tests.getTestById(testId);

		for (var ii = 0; ii < testObject.steps.length; ii++) {
			var stepObject = testObject.steps[ii];
			if (parseInt(stepObject.stepId) === stepId) {
				return stepObject;
			}
		}
	},
	updateTest: function(newTestObject) {
		if (typeof newTestObject !== 'object') {
			return;
		}

		var testId = parseInt(newTestObject.testId);
		for (var ii = Integrity.Tests.data.length - 1; ii >= 0; ii--) {
			var testObject = Integrity.Tests.data[ii];
			if (parseInt(testObject.testId) === testId) {
				Integrity.Tests.data[ii] = $.extend({}, newTestObject);
				return;
			}
		}
	},
	filterBySummary: function(aTests2Filter) {
		var sSummary = $('#testsListSearch').val();

		if (sSummary === L('global.search')) {
			sSummary = '';
		}

		if (sSummary) {
			return _.filter(aTests2Filter, function(oTest) {
				if (oTest.summary.indexOf(sSummary) > -1) {
					return oTest;
				}
			});
		} else {
			return aTests2Filter;
		}
	},
	filterByPlatform: function(aTests2Filter) {
		var nPlatformElements = $('.filters input[type="checkbox"]:checked');
		var aPlatforms = nPlatformElements.map(function() {
			return "platform_" + this.value;
		});

		if (aPlatforms.length) {
			return _.filter(aTests2Filter, function(oTest) {
				var bPlatformsPresent = _.all(
					aPlatforms,
					function(sPlatform) {
						return oTest.tags.indexOf(sPlatform) > -1
					}
				);

				if (bPlatformsPresent) {
					return oTest;
				}
			});
		} else {
			return aTests2Filter;
		}
	},
	filterByTestType: function(aTests2Filter) {
		var sTestType = $('.filters select').val();

		if (sTestType) {
			sTestType = "testType_" + sTestType;
		}

		if (sTestType) {
			return _.filter(aTests2Filter, function(oTest) {
				if (oTest.tags.indexOf(sTestType) > -1) {
					return oTest;
				}
			});
		} else {
			return aTests2Filter;
		}
	},
	filterByTags: function(aTests2Filter) {
		var oFilterData = {
			aTests2Filter: aTests2Filter,
			sTags: $('.filters input[name="tags"]').val() || ''
		};

		// lets try to filter by 'not' keyword
		oFilterData = Integrity.Tests.filterBy_NOT_Tags(oFilterData);
		// lets try to filter by 'or' keyword
		oFilterData = Integrity.Tests.filterBy_OR_Tags(oFilterData);
		// lets try to filter by 'and' keyword
		oFilterData = Integrity.Tests.filterBy_AND_Tags(oFilterData);

		// now time to return results
		return oFilterData.aTests2Filter;
	},
	filterBy_AND_Tags: function(oFilterData) {
		var aTests2Filter = oFilterData.aTests2Filter;
		// split by tags by space chars
		var aTags = oFilterData.sTags.replace(/\band\b/g, '').split(/\s+/);

		aTests2Filter = _.filter(aTests2Filter, function(oTest) {
			var bTagsPresent = _.all(aTags, function(sTag) {
				var oTagRegExp = new RegExp('\\b' + sTag + '\\b');
				return oTagRegExp.test(oTest.tags);
			});

			if (bTagsPresent) {
				return oTest;
			}
		});

		return {
			aTests2Filter: aTests2Filter,
			sTags: aTags.join(' ')
		};
	},
	filterBy_OR_Tags: function(oFilterData) {
		var sNextTag = null;
		var sPrevTag = null;
		var aTags = oFilterData.sTags.replace(/or(\s+or)+/g, 'or').split(/\s+/g);
		var aTests2Filter = oFilterData.aTests2Filter;

		for (var ii = 0; ii < aTags.length; ii++) {
			if (aTags[ii] === 'or') {
				sNextTag = aTags[ii + 1];
				sPrevTag = aTags[ii - 1];

				if (sNextTag && sPrevTag) {
					// filter tests from set that match to following condition
					aTests2Filter = _.filter(aTests2Filter, function(oTest) {
						var oTag1RegExp = new RegExp('\\b' + sNextTag + '\\b');
						var oTag2RegExp = new RegExp('\\b' + sPrevTag + '\\b');

						return
							oTag1RegExp.test(oTest.tags) ||
							oTag2RegExp.test(oTest.tags);
					});

					aTags[ii - 1] = '';
					aTags[ii] = '';
					aTags[ii + 1] = '';
				}
			}
		}

		return {
			aTests2Filter: aTests2Filter,
			sTags: _.map(
				aTags,
				function(sTag) {
					return sTag === 'or' ? '' : sTag;
				}
			).join(' ')
		};
	},
	filterBy_NOT_Tags: function(oFilterData) {
		var sNextTag = null;
		var aTags = oFilterData.sTags.split(/\s+/g);
		var aTests2Filter = oFilterData.aTests2Filter;

		for (var ii = 0; ii < aTags.length; ii++) {
			if (aTags[ii] === 'not') {
				sNextTag = aTags[ii + 1];

				if (sNextTag && sNextTag !== 'not') {
					// reject tests from set that has specified tag
					aTests2Filter = _.reject(aTests2Filter, function(oTest) {
						var oTagRegExp = new RegExp('\\b' + sNextTag + '\\b');
						return oTagRegExp.test(oTest.tags);
					});

					aTags[ii + 1] = '';
				}

				aTags[ii] = '';
			}
		}

		return {
			aTests2Filter: aTests2Filter,
			sTags: aTags.join(' ')
		};
	}
};

Integrity.Companies = {
	data: [],
	convertCallback: function(data) {
		var root = 'organizations';
		Integrity.Companies.data = $.extend(true, [], data[root]);
		var result = createGenericData4Grid(data[root]);

		for (var ii = 0; ii < result.rows.length; ii++) {
			Integrity.Companies.extendRow(result.rows[ii]);
		}

		return result;
	},
	extendRow: function(row) {
		if (typeof row === 'object') {
			row.activeStr = row.active ?
				L("global.active") : L("global.inactive");

			return row;
		} else {
			return {};
		}
	}
};

Integrity.Users = {
	data: [],
	convertCallback: function(data) {
		var root = 'users';
		Integrity.Users.data = $.extend(true, [], data[root]);
		var result = createGenericData4Grid(data[root]);

		for (var ii = 0; ii < result.rows.length; ii++) {
			Integrity.Users.extendRow(result.rows[ii]);
		}

		return result;
	},
	extendRow: function(row) {
		if (typeof row === 'object') {
			row.activeStr = parseInt(row.active) ?
				L("global.active") : L("global.inactive");

			switch (row.role) {
				case "superadmin":
					row.role_i18n = L("app.roles.superadmin");
					break;
				case "groupadmin":
					row.role_i18n = L("app.roles.groupadmin");
					break;
				case "testmanager":
					row.role_i18n = L("app.roles.testmanager");
					break;
				case "testwriter":
					row.role_i18n = L("app.roles.testwriter");
					break;
				case "tester":
					row.role_i18n = L("app.roles.tester");
			}

			return row;
		} else {
			return {};
		}
	},
	getUserById: function(id) {
		id = parseInt(id);
		for (var ii = Integrity.Users.data.length - 1; ii >= 0; ii--) {
			var tt = Integrity.Users.data[ii];
			if (parseInt(tt.userId) === id) {
				return tt;
			}
		}
	},
	updateUser: function(objNewUser) {
		if (typeof objNewUser !== 'object') {
			return;
		}

		var userId = parseInt(objNewUser.userId);
		for (var ii = Integrity.Users.data.length - 1; ii >= 0; ii--) {
			var objUser = Integrity.Users.data[ii];
			if (parseInt(objUser.userId) === userId) {
				Integrity.Users.data[ii] = $.extend({}, objNewUser);
				return;
			}
		}
	}
};

Integrity.Suites = {
	data: [],
	convertCallback: function(data) {
		var root = 'suites';
		Integrity.Suites.data = $.extend(true, [], data[root]);
		return createGenericData4Grid(data[root]);
	},
	getSuiteById: function(id) {
		id = parseInt(id);
		for (var ii = Integrity.Suites.data.length - 1; ii >= 0; ii--) {
			var tt = Integrity.Suites.data[ii];
			if (parseInt(tt.suiteId) === id) {
				return tt;
			}
		}
	},
	updateSuite: function(objNewSuite) {
		if (typeof objNewSuite !== 'object') {
			return;
		}

		var suiteId = parseInt(objNewSuite.suiteId);
		for (var ii = Integrity.Suites.data.length - 1; ii >= 0; ii--) {
			var objSuite = Integrity.Suites.data[ii];
			if (parseInt(objSuite.suiteId) === suiteId) {
				Integrity.Suites.data[ii] = $.extend({}, objNewSuite);
				return;
			}
		}
	}
};

Integrity.AssignedSuites = {
	data: [],
	convertCallback: function(data) {
		var root = 'suites';
		Integrity.AssignedSuites.data = $.extend(true, [], data[root]);
		var result = createGenericData4Grid(data[root]);

		for (var ii = 0; ii < result.rows.length; ii++) {
			Integrity.AssignedSuites.extendRow(result.rows[ii]);
		}

		return result;
	},
	extendRow: function(row) {
		if (typeof row === 'object') {
			var date = new Date(parseInt(row.assignedDate) * 1000);
			row.when = $.datepicker.formatDate('yy-mm-dd', date);
			row.whenRaw = date.getTime();

			row.assigner = row.assigner.username;
			return row;
		} else {
			return {}
		}
	}
};

Integrity.CompletedSuites = {
	data: [],
	convertCallback: function(data) {
		var root = 'suites';
		Integrity.CompletedSuites.data = $.extend(true, [], data[root]);
		var result = createGenericData4Grid(data[root]);

		for (var ii = 0; ii < result.rows.length; ii++) {
			Integrity.CompletedSuites.extendRow(result.rows[ii]);
		}

		return result;
	},
	extendRow: function(row) {
		if (typeof row === 'object') {
			var date = new Date(parseInt(row.assignedDate) * 1000);
			row.when = $.datepicker.formatDate('yy-mm-dd', date);
			row.whenRaw = date.getTime();

			var aTests = row.tests;
			row.assigner = row.assigner.username;
			row.success = !Boolean(_.detect(
				row.tests,
				function(oTest) {
					return _.detect(
						oTest.steps,
						function(oStep) {
							return oStep.success == false;
						}
					)
				}
			));

			return row;
		} else {
			return {}
		}
	},
	getSuiteById: function(iSuiteRunId) {
		iSuiteRunId = parseInt(iSuiteRunId);
		for (var ii = Integrity.CompletedSuites.data.length - 1; ii >= 0; ii--) {
			var oSuite = Integrity.CompletedSuites.data[ii];

			if (parseInt(oSuite.suiteRunId) === iSuiteRunId) {
				return oSuite;
			}
		}
	},
	convertSubgridCallback: function(oSuite, fnFilterCallback) {
		var oResult = Integrity.Tests.convertCallback(oSuite, true);

		_.each(oResult.rows, function(oTest) {
			var failedCommands = _.reduce(
				oTest.steps,
				function(memo, oStep) {
					return memo + Number(oStep.success === false);
				},
				0
			);

			var passedTestNotes = _.detect(oTest.steps, function(oStep) {
				return !(oStep.notes && oStep.success);
			});

			oTest.quality = '<span class="clickable">' + failedCommands +
				'/' + oTest.steps.length + '</span>';

			if (failedCommands) {
				oTest.state = '#f3acac';
			} else {
				if (passedTestNotes) {
					oTest.state = '#aae3a4';
				} else {
					oTest.state = '#eefb58';
				}
			}
		});

		if (fnFilterCallback) {
			return _.filter(oResult.rows, fnFilterCallback);
		} else {
			return oResult;
		}
	}
};

Integrity.SuiteRun = {
	data: [],
	allTests: {},
	allSteps: {},
	stepId2test: {},
	prepare: function(){
		_.each(Integrity.SuiteRun.data.tests, function(test){
			if(test.steps == null){
				test.steps = [];
			}
			Integrity.SuiteRun.allTests[test.testId] = test;

			_.each(test.steps, function(step){
				Integrity.SuiteRun.allSteps[step.stepId] = step;
				Integrity.SuiteRun.stepId2test[step.stepId] = test;

				if(step.attachments == null){
					step.attachments = [];
				}
			});
		});
	},
	getTestById: function(testId){
		return Integrity.SuiteRun.allTests[testId];
	},
	getTestIndexById: function(testId){
		for(var ii = Integrity.SuiteRun.data.tests.length - 1; ii >= 0; ii--){
			if(Integrity.SuiteRun.data.tests[ii].testId == testId){
				return ii;
			}
		}
		return;
	},
	getNextTestByTestId: function(testId){
		var ind = Integrity.SuiteRun.getTestIndexById(testId);
		if(ind != Integrity.SuiteRun.data.tests.length - 1){
			return Integrity.SuiteRun.data.tests[ind + 1];
		}
		return;
	},
	getStepById: function(stepId){
		return Integrity.SuiteRun.allSteps[stepId];
	},
	getStepIndexByStepId: function(stepId){
		var test = Integrity.SuiteRun.getTestByStepId(stepId);
		if(test == null || test.steps == null){
			return;
		}
		for(var ii = test.steps.length - 1; ii >= 0; ii--){
			if(test.steps[ii].stepId == stepId){
				return ii;
			}
		}
		return;
	},
	getTestByStepId: function(stepId){
		return Integrity.SuiteRun.stepId2test[stepId];
	},
	getNextStepByStepId: function(stepId){
		var test = Integrity.SuiteRun.getTestByStepId(stepId);
		var ind = Integrity.SuiteRun.getStepIndexByStepId(stepId);

		if(test == null){
			return;
		}

		if(test.steps == null){
			return;
		}
		if(ind != test.steps.length - 1){
			return test.steps[ind + 1];
		}
		return;
	}
};

Integrity.testersData = [];


