/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function() {
	'use strict';

	var featureControllers = angular.module("featureControllers");
	var feature = featureControllers.register("common");

	// ==============================================================
	// =                          Function                          =
	// ==============================================================
	feature.service("Policy", function(Entities) {
		var Policy = function () {};

		Policy.updatePolicyStatus = function(policy, status) {
			$.dialog({
				title: "Confirm",
				content: "Do you want to " + (status ? "enable" : "disable") + " policy[" + policy.tags.policyId + "]?",
				confirm: true
			}, function(ret) {
				if(ret) {
					policy.enabled = status;
					Entities.updateEntity("AlertDefinitionService", policy);
				}
			});
		};
		Policy.deletePolicy = function(policy, callback) {
			$.dialog({
				title: "Confirm",
				content: "Do you want to delete policy[" + policy.tags.policyId + "]?",
				confirm: true
			}, function(ret) {
				if(ret) {
					policy.enabled = status;
					Entities.deleteEntity("AlertDefinitionService", policy)._promise.finally(function() {
						if(callback) {
							callback(policy);
						}
					});
				}
			});
		};
		return Policy;
	});

	feature.service("Notification", function(Entities) {
		var Notification = function () {};
		Notification.map = {};

		Notification.list = Entities.queryEntities("AlertNotificationService");
		Notification.list._promise.then(function () {
			$.each(Notification.list, function (i, notification) {
				// Parse fields
				notification.fieldList = common.parseJSON(notification.fields, []);

				// Fill map
				Notification.map[notification.tags.notificationType] = notification;
			});
		});

		Notification.promise = Notification.list._promise;

		return Notification;
	});

	// ==============================================================
	// =                          Policies                          =
	// ==============================================================

	// ========================= Policy List ========================
	feature.navItem("policyList", "Policies", "list");
	feature.controller('policyList', function(PageConfig, Site, $scope, Application, Entities, Policy) {
		PageConfig.pageTitle = "Policy List";
		PageConfig.pageSubTitle = Site.current().tags.site;

		// Initial load
		$scope.policyList = [];
		$scope.application = Application.current();

		// List policies
		var _policyList = Entities.queryEntities("AlertDefinitionService", {site: Site.current().tags.site, application: $scope.application.tags.application});
		_policyList._promise.then(function() {
			$.each(_policyList, function(i, policy) {
				policy.__expression = common.parseJSON(policy.policyDef, {}).expression;

				$scope.policyList.push(policy);
			});
		});
		$scope.policyList._promise = _policyList._promise;

		// Function
		$scope.searchFunc = function(item) {
			var key = $scope.search;
			if(!key) return true;

			var _key = key.toLowerCase();
			function _hasKey(item, path) {
				var _value = common.getValueByPath(item, path, "").toLowerCase();
				return _value.indexOf(_key) !== -1;
			}
			return _hasKey(item, "tags.policyId") || _hasKey(item, "__expression") || _hasKey(item, "description") || _hasKey(item, "owner");
		};

		$scope.updatePolicyStatus = Policy.updatePolicyStatus;
		$scope.deletePolicy = function(policy) {
			Policy.deletePolicy(policy, function(policy) {
				var _index = $scope.policyList.indexOf(policy);
				$scope.policyList.splice(_index, 1);
			});
		};
	});

	// ======================= Policy Detail ========================
	feature.controller('policyDetail', function(PageConfig, Site, $scope, $wrapState, $interval, Entities, Policy, nvd3) {
		var MAX_PAGESIZE = 10000;
		var seriesRefreshInterval;

		PageConfig.pageTitle = "Policy Detail";
		PageConfig.lockSite = true;
		PageConfig
			.addNavPath("Policy List", "/common/policyList")
			.addNavPath("Policy Detail");

		$scope.chartConfig = {
			chart: "line",
			xType: "time"
		};

		// Query policy
		if($wrapState.param.filter) {
			$scope.policyList = Entities.queryEntity("AlertDefinitionService", $wrapState.param.filter);
		} else {
			$scope.policyList = Entities.queryEntities("AlertDefinitionService", {
				policyId: $wrapState.param.policy,
				site: $wrapState.param.site,
				alertExecutorId: $wrapState.param.executor
			});
		}

		$scope.policyList._promise.then(function() {
			var policy = null;

			if($scope.policyList.length === 0) {
				$.dialog({
					title: "OPS!",
					content: "Policy not found!"
				}, function() {
					location.href = "#/common/policyList";
				});
				return;
			} else {
				policy = $scope.policyList[0];

				policy.__notificationList = common.parseJSON(policy.notificationDef, []);

				policy.__expression = common.parseJSON(policy.policyDef, {}).expression;

				$scope.policy = policy;
				Site.current(Site.find($scope.policy.tags.site));
				console.log($scope.policy);
			}

			// Visualization
			var _intervalType = 0;
			var _intervalList = [
				["Daily", 1440, function() {
					var _endTime = app.time.now().hour(23).minute(59).second(59).millisecond(0);
					var _startTime = _endTime.clone().subtract(1, "month").hour(0).minute(0).second(0).millisecond(0);
					return [_startTime, _endTime];
				}],
				["Hourly", 60, function() {
					var _endTime = app.time.now().minute(59).second(59).millisecond(0);
					var _startTime = _endTime.clone().subtract(48, "hour").minute(0).second(0).millisecond(0);
					return [_startTime, _endTime];
				}],
				["Every 5 minutes", 5, function() {
					var _endTime = app.time.now().second(59).millisecond(0);
					var _minute = Math.floor(_endTime.minute() / 5) * 5;
					var _startTime = _endTime.clone().minute(_minute).subtract(5 * 30, "minute").second(0).millisecond(0);
					_endTime.minute(_minute + 4);
					return [_startTime, _endTime];
				}]
			];

			function _loadSeries(seriesName, metricName, condition) {
				var list = Entities.querySeries("GenericMetricService", $.extend({_metricName: metricName}, condition), "@site", "sum(value)", _intervalList[_intervalType][1]);
				var seriesList = nvd3.convert.eagle([list]);
				if(!$scope[seriesName]) $scope[seriesName] = seriesList;
				list._promise.then(function() {
					$scope[seriesName] = seriesList;
				});
			}

			function refreshSeries() {
				var _timeRange = _intervalList[_intervalType][2]();
				var _startTime = _timeRange[0];
				var _endTime = _timeRange[1];
				var _cond = {
					application: policy.tags.application,
					policyId: policy.tags.policyId,
					_startTime: _startTime,
					_endTime: _endTime
				};
				console.log("Range:", common.format.date(_startTime, "datetime"), common.format.date(_endTime, "datetime"));

				// > eagle.policy.eval.count
				_loadSeries("policyEvalSeries", "eagle.policy.eval.count", _cond);

				// > eagle.policy.eval.fail.count
				_loadSeries("policyEvalFailSeries", "eagle.policy.eval.fail.count", _cond);

				// > eagle.alert.count
				_loadSeries("alertSeries", "eagle.alert.count", _cond);

				// > eagle.alert.fail.count
				_loadSeries("alertFailSeries", "eagle.alert.fail.count", _cond);
			}

			// Alert list
			$scope.alertList = Entities.queryEntities("AlertService", {
				site: Site.current().tags.site,
				application: policy.tags.application,
				policyId: policy.tags.policyId,
				_pageSize: MAX_PAGESIZE,
				_duration: 1000 * 60 * 60 * 24 * 30,
				__ETD: 1000 * 60 * 60 * 24
			});

			refreshSeries();
			seriesRefreshInterval = $interval(refreshSeries, 60000);

			// Menu
			$scope.visualizationMenu = [
				{icon: "clock-o", title: "Interval", list:
					$.map(_intervalList, function(item, index) {
						var _item = {icon: "clock-o", title: item[0], func: function() {
							_intervalType = index;
							refreshSeries();
						}};
						Object.defineProperty(_item, 'strong', {
							get: function() {return _intervalType === index;}
						});
						return _item;
					})
				}
			];
		});

		// Function
		$scope.updatePolicyStatus = Policy.updatePolicyStatus;
		$scope.deletePolicy = function(policy) {
			Policy.deletePolicy(policy, function() {
				location.href = "#/common/policyList";
			});
		};

		// Clean up
		$scope.$on('$destroy', function() {
			$interval.cancel(seriesRefreshInterval);
		});
	});

	// ======================== Policy Edit =========================
	function policyCtrl(create, PageConfig, Site, Policy, $scope, $wrapState, $q, UI, Entities, Application, Authorization, Notification) {
		PageConfig.pageTitle = create ? "Policy Create" : "Policy Edit";
		PageConfig.pageSubTitle = Site.current().tags.site;
		PageConfig
			.addNavPath("Policy List", "/common/policyList")
			.addNavPath("Policy Edit");

		var _winTimeDesc = "Number unit[millisecond, sec, min, hour, day, month, year]. e.g. 23 sec";
		var _winTimeRegex = /^\d+\s+(millisecond|milliseconds|second|seconds|sec|minute|minutes|min|hour|hours|day|days|week|weeks|month|months|year|years)$/;
		var _winTimeDefaultValue = '10 min';
		$scope.config = {
			window: [
				// Display name, window type, required columns[Title, Description || "LONG_FIELD", Regex check, default value]
				{
					title: "Message Time Slide",
					description: "Using timestamp filed from input is used as event's timestamp",
					type: "externalTime",
					fields:[
						{title: "Field", defaultValue: "timestamp", hide: true},
						{title: "Time", description: _winTimeDesc, regex: _winTimeRegex, defaultValue: _winTimeDefaultValue}
					]
				},
				{
					title: "System Time Slide",
					description: "Using System time is used as timestamp for event's timestamp",
					type: "time",
					fields:[
						{title: "Time", description: _winTimeDesc, regex: _winTimeRegex, defaultValue: _winTimeDefaultValue}
					]
				},
				{
					title: "System Time Batch",
					description: "Same as System Time Window except the policy is evaluated at fixed duration",
					type: "timeBatch",
					fields:[
						{title: "Time", description: _winTimeDesc, regex: _winTimeRegex, defaultValue: _winTimeDefaultValue}
					]
				},
				{
					title: "Length Slide",
					description: "The slide window has a fixed length",
					type: "length",
					fields:[
						{title: "Number", description: "Number only. e.g. 1023", regex: /^\d+$/}
					]
				},
				{
					title: "Length Batch",
					description: "Same as Length window except the policy is evaluated in batch mode when fixed event count reached",
					type: "lengthBatch",
					fields:[
						{title: "Number", description: "Number only. e.g. 1023", regex: /^\d+$/}
					]
				}
			]
		};

		$scope.Notification = Notification;

		$scope.create = create;
		$scope.encodedRowkey = $wrapState.param.filter;

		$scope.step = 0;
		$scope.applications = {};
		$scope.policy = {};

		// ==========================================
		// =              Notification              =
		// ==========================================
		$scope.notificationTabHolder = null;

		$scope.newNotification = function (notificationType) {
			var __notification = {
				notificationType: notificationType
			};

			$.each(Notification.map[notificationType].fieldList, function (i, field) {
				__notification[field.name] = field.value || "";
			});

			$scope.policy.__.notification.push(__notification);
		};

		Notification.promise.then(function () {
			$scope.menu = Authorization.isRole('ROLE_ADMIN') ? [
				{icon: "cog", title: "Configuration", list: [
					{icon: "trash", title: "Delete", danger: true, func: function () {
						var notification = $scope.notificationTabHolder.selectedPane.data;
						UI.deleteConfirm(notification.notificationType).then(null, null, function(holder) {
							common.array.remove(notification, $scope.policy.__.notification);
							holder.closeFunc();
						});
					}}
				]},
				{icon: "plus", title: "New", list: $.map(Notification.list, function(notification) {
					return {
						icon: "plus",
						title: notification.tags.notificationType,
						func: function () {
							$scope.newNotification(notification.tags.notificationType);
							setTimeout(function() {
								$scope.notificationTabHolder.setSelect(-1);
								$scope.$apply();
							}, 0);
						}
					};
				})}
			] : [];
		});

		// ==========================================
		// =            Data Preparation            =
		// ==========================================
		// Steam list
		var _streamList = Entities.queryEntities("AlertStreamService", {application: Application.current().tags.application});
		var _executorList = Entities.queryEntities("AlertExecutorService", {application: Application.current().tags.application});
		$scope.streamList = _streamList;
		$scope.executorList = _executorList;
		$scope.streamReady = false;

		$q.all([_streamList._promise, _executorList._promise]).then(function() {
			// Map executor with stream
			$.each(_executorList, function(i, executor) {
				$.each(_streamList, function(j, stream) {
					if(stream.tags.application === executor.tags.application && stream.tags.streamName === executor.tags.streamName) {
						stream.alertExecutor = executor;
						return false;
					}
				});
			});

			// Fill stream list
			$.each(_streamList, function(i, unit) {
				var _srcStreamList = $scope.applications[unit.tags.application] = $scope.applications[unit.tags.application] || [];
				_srcStreamList.push(unit);
			});

			$scope.streamReady = true;

			// ==========================================
			// =                Function                =
			// ==========================================
			function _findStream(application, streamName) {
				var _streamList = $scope.applications[application];
				if(!_streamList) return null;

				for(var i = 0 ; i < _streamList.length ; i += 1) {
					if(_streamList[i].tags.streamName === streamName) {
						return _streamList[i];
					}
				}
				return null;
			}

			// ==========================================
			// =              Step control              =
			// ==========================================
			$scope.steps = [
				// >> Select stream
				{
					title: "Select Stream",
					ready: function() {
						return $scope.streamReady;
					},
					init: function() {
						$scope.policy.__.streamName = $scope.policy.__.streamName ||
							common.array.find($scope.policy.tags.application, _streamList, "tags.application").tags.streamName;
					},
					nextable: function() {
						var _streamName = common.getValueByPath($scope.policy, "__.streamName");
						if(!_streamName) return false;

						// Detect stream in current data source list
						return !!common.array.find(_streamName, $scope.applications[$scope.policy.tags.application], "tags.streamName");
					}
				},

				// >> Define Alert Policy
				{
					title: "Define Alert Policy",
					init: function() {
						// Normal mode will fetch meta list
						if(!$scope.policy.__.advanced) {
							var _stream = _findStream($scope.policy.tags.application, $scope.policy.__.streamName);
							$scope._stream = _stream;

							if(!_stream) {
								$.dialog({
									title: "OPS",
									content: "Stream not found! Current application don't match any stream."
								});
								return;
							}

							if(!_stream.metas) {
								_stream.metas = Entities.queryEntities("AlertStreamSchemaService", {application: $scope.policy.tags.application, streamName: $scope.policy.__.streamName});
								_stream.metas._promise.then(function() {
									_stream.metas.sort(function(a, b) {
										if(a.tags.attrName < b.tags.attrName) {
											return -1;
										} else if(a.tags.attrName > b.tags.attrName) {
											return 1;
										}
										return 0;
									});
								});
							}
						}
					},
					ready: function() {
						if(!$scope.policy.__.advanced) {
							return $scope._stream.metas._promise.$$state.status === 1;
						}
						return true;
					},
					nextable: function() {
						if($scope.policy.__.advanced) {
							// Check stream source
							$scope._stream = null;
							$.each($scope.applications[$scope.policy.tags.application], function(i, stream) {
								if(($scope.policy.__._expression || "").indexOf(stream.tags.streamName) !== -1) {
									$scope._stream = stream;
									return false;
								}
							});
							return $scope._stream;
						} else {
							// Window
							if($scope.policy.__.windowConfig) {
								var _winMatch = true;
								var _winConds = $scope.getWindow().fields;
								$.each(_winConds, function(i, cond) {
									if(!(cond.val || "").match(cond.regex)) {
										_winMatch = false;
										return false;
									}
								});
								if(!_winMatch) return false;

								// Aggregation
								if($scope.policy.__.groupAgg) {
									if(!$scope.policy.__.groupAggPath ||
										!$scope.policy.__.groupCondOp ||
										!$scope.policy.__.groupCondVal) {
										return false;
									}
								}
							}
						}
						return true;
					}
				},

				// >> Configuration & Notification
				{
					title: "Configuration & Notification",
					nextable: function() {
						return !!$scope.policy.tags.policyId;
					}
				}
			];

			// ==========================================
			// =              Policy Logic              =
			// ==========================================
			_streamList._promise.then(function() {
				// Initial policy entity
				if(create) {
					$scope.policy = {
						__: {
							toJSON: jQuery.noop,
							conditions: {},
							notification: [],
							dedupe: {
								alertDedupIntervalMin: 10,
								fields: []
							},
							_dedupTags: {},
							policy: {},
							window: "externalTime",
							group: "",
							groupAgg: "count",
							groupAggPath: "timestamp",
							groupCondOp: ">=",
							groupCondVal: "2"
						},
						description: "",
						enabled: true,
						prefix: "alertdef",
						remediationDef: "",
						tags: {
							application: Application.current().tags.application,
							policyType: "siddhiCEPEngine"
						}
					};

					// If configured data source
					if($wrapState.param.app) {
						$scope.policy.tags.application = $wrapState.param.app;
						if(common.array.find($wrapState.param.app, Site.current().applicationList, "tags.application")) {
							setTimeout(function() {
								$scope.changeStep(0, 2, false);
								$scope.$apply();
							}, 1);
						}
					}

					// Start step
					$scope.changeStep(0, 1, false);
					console.log($scope.policy);
				} else {
					var _policy = Entities.queryEntity("AlertDefinitionService", $scope.encodedRowkey);
					_policy._promise.then(function() {
						if(_policy.length) {
							$scope.policy = _policy[0];
							$scope.policy.__ = {
								toJSON: jQuery.noop
							};

							Site.current(Site.find($scope.policy.tags.site));
						} else {
							$.dialog({
								title: "OPS",
								content: "Policy not found!"
							}, function() {
								$wrapState.path("/common/policyList");
								$scope.$apply();
							});
							return;
						}

						var _application = Application.current();
						if(_application.tags.application !== $scope.policy.tags.application) {
							_application = Application.find($scope.policy.tags.application);
							if(_application) {
								Application.current(_application, false);
								console.log("Application not match. Do reload...");
								$wrapState.reload();
							} else {
								$.dialog({
									title: "OPS",
									content: "Application not found! Current policy don't match any application."
								}, function() {
									$location.path("/common/policyList");
									$scope.$apply();
								});
							}
							return;
						}

						// === Revert inner data ===
						// >> De-dupe
						$scope.policy.__._dedupTags = {};
						$scope.policy.__.dedupe = common.parseJSON($scope.policy.dedupeDef, {});
						$.each($scope.policy.__.dedupe.fields || [], function (i, field) {
							$scope.policy.__._dedupTags[field] = true;
						});

						// >> Notification
						$scope.policy.__.notification = common.parseJSON($scope.policy.notificationDef, []);

						// >> Policy
						var _policyUnit = $scope.policy.__.policy = common.parseJSON($scope.policy.policyDef);

						// >> Parse expression
						$scope.policy.__.conditions = {};
						var _condition = _policyUnit.expression.match(/from\s+(\w+)(\[(.*)])?(#window[^\)]*\))?\s+(select (\w+, )?(\w+)\((\w+)\) as [\w\d_]+ (group by (\w+) )?having ([\w\d_]+) ([<>=]+) ([^\s]+))?/);
						var _cond_stream, _cond_query, _cond_window, _cond_group, _cond_groupUnit;

						if(!_condition) {
							$scope.policy.__.advanced = true;
						} else {
							_cond_stream = _condition[1];
							_cond_query = _condition[3] || "";
							_cond_window = _condition[4];
							_cond_group = _condition[5];
							_cond_groupUnit = _condition.slice(7,14);

							// > StreamName
							var _streamName = _cond_stream;
							var _cond = _cond_query;

							$scope.policy.__.streamName = _streamName;

							// > Conditions
							// Loop condition groups
							if(_cond.trim() !== "" && /^\(.*\)$/.test(_cond)) {
								var _condGrps = _cond.substring(1, _cond.length - 1).split(/\)\s+and\s+\(/);
								$.each(_condGrps, function(i, line) {
									// Loop condition cells
									var _condCells = line.split(/\s+or\s+/);
									$.each(_condCells, function(i, cell) {
										var _opMatch = cell.match(/(\S*)\s*(==|!=|>|<|>=|<=|contains)\s*('(?:[^'\\]|\\.)*'|[\w\d]+)/);
										if(!common.isEmpty(_opMatch)) {
											var _key = _opMatch[1];
											var _op = _opMatch[2];
											var _val = _opMatch[3];
											var _conds = $scope.policy.__.conditions[_key] = $scope.policy.__.conditions[_key] || [];
											var _type = "";
											if(_val.match(/'.*'/)) {
												_val = _val.slice(1, -1);
												_type = "string";
											} else if(_val === "true" || _val === "false") {
												var _regexMatch = _key.match(/^str:regexp\((\w+),'(.*)'\)/);
												var _containsMatch = _key.match(/^str:contains\((\w+),'(.*)'\)/);
												var _mathes = _regexMatch || _containsMatch;
												if(_mathes) {
													_key = _mathes[1];
													_val = _mathes[2];
													_type = "string";
													_op = _regexMatch ? "regex" : "contains";
													_conds = $scope.policy.__.conditions[_key] = $scope.policy.__.conditions[_key] || [];
												} else {
													_type = "bool";
												}
											} else {
												_type = "number";
											}
											_conds.push($scope._CondUnit(_key, _op, _val, _type));
										}
									});
								});
							} else if(_cond_query !== "") {
								$scope.policy.__.advanced = true;
							}
						}

						if($scope.policy.__.advanced) {
							$scope.policy.__._expression = _policyUnit.expression;
						} else {
							// > window
							if(!_cond_window) {
								$scope.policy.__.window = "externalTime";
								$scope.policy.__.group = "";
								$scope.policy.__.groupAgg = "count";
								$scope.policy.__.groupAggPath = "timestamp";
								$scope.policy.__.groupCondOp = ">=";
								$scope.policy.__.groupCondVal = "2";
							} else {
								try {
									$scope.policy.__.windowConfig = true;

									var _winCells = _cond_window.match(/\.(\w+)\((.*)\)/);
									$scope.policy.__.window = _winCells[1];
									var _winConds = $scope.getWindow().fields;
									$.each(_winCells[2].split(","), function(i, val) {
										_winConds[i].val = val;
									});

									// Group
									if(_cond_group) {
										$scope.policy.__.group = _cond_groupUnit[3];
										$scope.policy.__.groupAgg = _cond_groupUnit[0];
										$scope.policy.__.groupAggPath = _cond_groupUnit[1];
										$scope.policy.__.groupAggAlias = _cond_groupUnit[4] === "aggValue" ? "" : _cond_groupUnit[4];
										$scope.policy.__.groupCondOp = _cond_groupUnit[5];
										$scope.policy.__.groupCondVal = _cond_groupUnit[6];
									} else {
										$scope.policy.__.group = "";
										$scope.policy.__.groupAgg = "count";
										$scope.policy.__.groupAggPath = "timestamp";
										$scope.policy.__.groupCondOp = ">=";
										$scope.policy.__.groupCondVal = "2";
									}
								} catch(err) {
									$scope.policy.__.window = "externalTime";
								}
							}
						}

						$scope.changeStep(0, 2, false);
						console.log($scope.policy);
					});
				}
			});

			// ==========================================
			// =                Function                =
			// ==========================================
			// UI: Highlight select step
			$scope.stepSelect = function(step) {
				return step === $scope.step ? "active" : "";
			};

			// UI: Collapse all
			$scope.collapse = function(cntr) {
				var _list = $(cntr).find(".collapse").css("height", "auto");
				if(_list.hasClass("in")) {
					_list.removeClass("in");
				} else {
					_list.addClass("in");
				}
			};

			// Step process. Will fetch target step attribute and return boolean
			function _check(key, step) {
				var _step = $scope.steps[step - 1];
				if(!_step) return;

				var _value = _step[key];
				if(typeof _value === "function") {
					return _value();
				} else if(typeof _value === "boolean") {
					return _value;
				}
				return true;
			}
			// Check step is ready. Otherwise will display load animation
			$scope.stepReady = function(step) {
				return _check("ready", step);
			};
			// Check whether process next step. Otherwise will disable next button
			$scope.checkNextable = function(step) {
				return !_check("nextable", step);
			};
			// Switch step
			$scope.changeStep = function(step, targetStep, check) {
				if(check === false || _check("checkStep", step)) {
					$scope.step =  targetStep;

					_check("init", targetStep);
				}
			};

			// Window
			$scope.getWindow = function() {
				if(!$scope.policy || !$scope.policy.__) return null;
				return common.array.find($scope.policy.__.window, $scope.config.window, "type");
			};

			// Aggregation
			$scope.groupAggPathList = function() {
				return $.grep(common.getValueByPath($scope, "_stream.metas", []), function(meta) {
					return $.inArray(meta.attrType, ['long','integer','number', 'double', 'float']) !== -1;
				});
			};

			$scope.updateGroupAgg = function() {
				$scope.policy.__.groupAggPath = $scope.policy.__.groupAggPath || common.getValueByPath($scope.groupAggPathList()[0], "tags.attrName");

				if($scope.policy.__.groupAgg === 'count') {
					$scope.policy.__.groupAggPath = 'timestamp';
				}
			};

			// Resolver
			$scope.resolverTypeahead = function(value, resolver) {
				var _resolverList = Entities.query("stream/attributeresolve", {
					site: Site.current().tags.site,
					resolver: resolver,
					query: value
				});
				return _resolverList._promise.then(function() {
					return _resolverList;
				});
			};

			// Used for input box when pressing enter
			$scope.conditionPress = function(event) {
				if(event.which == 13) {
					setTimeout(function() {
						$(event.currentTarget).closest(".input-group").find("button").click();
					}, 1);
				}
			};
			// Check whether has condition
			$scope.hasCondition = function(key, type) {
				var _list = common.getValueByPath($scope.policy.__.conditions, key, []);
				if(_list.length === 0) return false;

				if(type === "bool") {
					return !_list[0].ignored();
				}
				return true;
			};
			// Condition unit definition
			$scope._CondUnit = function(key, op, value, type) {
				return {
					key: key,
					op: op,
					val: value,
					type: type,
					ignored: function() {
						return this.type === "bool" && this.val === "none";
					},
					getVal: function() {
						return this.type === "string" ? "'" + this.val + "'" : this.val;
					},
					toString: function() {
						return this.op + " " + this.getVal();
					},
					toCondString: function() {
						var _op = this.op === "=" ? "==" : this.op;
						if(_op === "regex") {
							return "str:regexp(" + this.key + "," + this.getVal() + ")==true";
						} else if(_op === "contains") {
							return "str:contains(" + this.key + "," + this.getVal() + ")==true";
						} else {
							return this.key + " " + _op + " " + this.getVal();
						}
					}
				};
			};
			// Add condition for policy
			$scope.addCondition = function(key, op, value, type) {
				if(value === "" || value === undefined) return false;

				var _condList = $scope.policy.__.conditions[key] = $scope.policy.__.conditions[key] || [];
				_condList.push($scope._CondUnit(key, op, value, type));
				return true;
			};
			// Convert condition list to description string
			$scope.parseConditionDesc = function(key) {
				return $.map($scope.policy.__.conditions[key] || [], function(cond) {
					if(!cond.ignored()) return "[" + cond.toString() + "]";
				}).join(" or ");
			};

			// To query
			$scope.toQuery = function() {
				if(!$scope.policy.__) return "";

				if($scope.policy.__.advanced) return $scope.policy.__._expression;

				// > Query
				var _query = $.map(common.getValueByPath($scope.policy, "__.conditions", {}), function(list) {
					var _conds = $.map(list, function(cond) {
						if(!cond.ignored()) return cond.toCondString();
					});
					if(_conds.length) {
						return "(" + _conds.join(" or ") + ")";
					}
				}).join(" and ");
				if(_query) {
					_query = "[" + _query + "]";
				}

				// > Window
				var _window = $scope.getWindow();
				var _windowStr = "";
				if($scope.policy.__.windowConfig) {
					_windowStr = $.map(_window.fields, function(field) {
						return field.val;
					}).join(",");
					_windowStr = "#window." + _window.type + "(" + _windowStr + ")";

					// > Group
					if($scope.policy.__.group) {
						_windowStr += common.template(" select ${group}, ${groupAgg}(${groupAggPath}) as ${groupAggAlias} group by ${group} having ${groupAggAlias} ${groupCondOp} ${groupCondVal}", {
							group: $scope.policy.__.group,
							groupAgg: $scope.policy.__.groupAgg,
							groupAggPath: $scope.policy.__.groupAggPath,
							groupCondOp: $scope.policy.__.groupCondOp,
							groupCondVal: $scope.policy.__.groupCondVal,
							groupAggAlias: $scope.policy.__.groupAggAlias || "aggValue"
						});
					} else {
						_windowStr += common.template(" select ${groupAgg}(${groupAggPath}) as ${groupAggAlias} having ${groupAggAlias} ${groupCondOp} ${groupCondVal}", {
							groupAgg: $scope.policy.__.groupAgg,
							groupAggPath: $scope.policy.__.groupAggPath,
							groupCondOp: $scope.policy.__.groupCondOp,
							groupCondVal: $scope.policy.__.groupCondVal,
							groupAggAlias: $scope.policy.__.groupAggAlias || "aggValue"
						});
					}
				} else {
					_windowStr = " select *";
				}

				return common.template("from ${stream}${query}${window} insert into outputStream;", {
					stream: $scope.policy.__.streamName,
					query: _query,
					window: _windowStr
				});
			};

			// ==========================================
			// =             Update Policy              =
			// ==========================================
			// dedupeDef notificationDef policyDef
			$scope.finishPolicy = function() {
				$scope.lock = true;

				// dedupeDef
				$scope.policy.__.dedupe.fields = $.map($scope.policy.__._dedupTags, function (value, key) {
					if(value) return key;
				});
				$scope.policy.dedupeDef = JSON.stringify($scope.policy.__.dedupe);

				// notificationDef
				$scope.policy.__.notification = $scope.policy.__.notification || [];

				$scope.policy.notificationDef = JSON.stringify($scope.policy.__.notification);

				// policyDef
				$scope.policy.__.policy = {
					expression: $scope.toQuery(),
					type: "siddhiCEPEngine"
				};
				$scope.policy.policyDef = JSON.stringify($scope.policy.__.policy);

				// alertExecutorId
				if($scope._stream.alertExecutor) {
					$scope.policy.tags.alertExecutorId = $scope._stream.alertExecutor.tags.alertExecutorId;
				} else {
					$scope.lock = false;
					$.dialog({
						title: "OPS!",
						content: "Alert Executor not defined! Please check 'AlertExecutorService'!"
					});
					return;
				}

				// site
				$scope.policy.tags.site = $scope.policy.tags.site || Site.current().tags.site;

				// owner
				$scope.policy.owner = Authorization.userProfile.username;

				// Update function
				function _updatePolicy() {
					Entities.updateEntity("AlertDefinitionService", $scope.policy)._promise.success(function(data) {
						$.dialog({
							title: "Success",
							content: (create ? "Create" : "Update") + " success!"
						}, function() {
							if(data.success) {
								location.href = "#/common/policyList";
							} else {
								$.dialog({
									title: "OPS",
									content: (create ? "Create" : "Update") + "failed!" + JSON.stringify(data)
								});
							}
						});

						$scope.create = create = false;
						$scope.encodedRowkey = data.obj[0];
					}).error(function(data) {
						$.dialog({
							title: "OPS",
							content: (create ? "Create" : "Update") + "failed!" + JSON.stringify(data)
						});
					}).then(function() {
						$scope.lock = false;
					});
				}

				// Check if already exist
				if($scope.create) {
					var _checkList = Entities.queryEntities("AlertDefinitionService", {
						alertExecutorId: $scope.policy.tags.alertExecutorId,
						policyId: $scope.policy.tags.policyId,
						policyType: "siddhiCEPEngine",
						application: $scope.policy.tags.application
					});
					_checkList._promise.then(function() {
						if(_checkList.length) {
							$.dialog({
								title: "Override Confirm",
								content: "Already exists PolicyID '" + $scope.policy.tags.policyId + "'. Do you want to override?",
								confirm: true
							}, function(ret) {
								if(ret) {
									_updatePolicy();
								} else {
									$scope.lock = false;
									$scope.$apply();
								}
							});
						} else {
							_updatePolicy();
						}
					});
				} else {
					_updatePolicy();
				}
			};
		});
	}

	feature.controller('policyCreate', function(PageConfig, Site, Policy, $scope, $wrapState, $q, UI, Entities, Application, Authorization, Notification) {
		var _args = [true];
		_args.push.apply(_args, arguments);
		policyCtrl.apply(this, _args);
	}, "policyEdit");
	feature.controller('policyEdit', function(PageConfig, Site, Policy, $scope, $wrapState, $q, UI, Entities, Application, Authorization, Notification) {
		PageConfig.lockSite = true;
		var _args = [false];
		_args.push.apply(_args, arguments);
		policyCtrl.apply(this, _args);
	});

	// ==============================================================
	// =                           Alerts                           =
	// ==============================================================

	// ========================= Alert List =========================
	feature.navItem("alertList", "Alerts", "exclamation-triangle");
	feature.controller('alertList', function(PageConfig, Site, $scope, $wrapState, $interval, $timeout, Entities, Application) {
		PageConfig.pageSubTitle = Site.current().tags.site;

		var MAX_PAGESIZE = 10000;

		// Initial load
		$scope.application = Application.current();

		$scope.alertList = [];
		$scope.alertList.ready = false;

		// Load data
		function _loadAlerts() {
			if($scope.alertList._promise) {
				$scope.alertList._promise.abort();
			}

			var _list = Entities.queryEntities("AlertService", {
				site: Site.current().tags.site,
				application: $scope.application.tags.application,
				_pageSize: MAX_PAGESIZE,
				_duration: 1000 * 60 * 60 * 24 * 30,
				__ETD: 1000 * 60 * 60 * 24
			});
			$scope.alertList._promise = _list._promise;
			_list._promise.then(function() {
				var index;

				if($scope.alertList[0]) {
					// List new alerts
					for(index = 0 ; index < _list.length ; index += 1) {
						var _alert = _list[index];
						_alert.__new = true;
						if(_alert.encodedRowkey === $scope.alertList[0].encodedRowkey) {
							break;
						}
					}

					if(index > 0) {
						$scope.alertList.unshift.apply($scope.alertList, _list.slice(0, index));

						// Clean up UI highlight
						$timeout(function() {
							$.each(_list, function(i, alert) {
								delete alert.__new;
							});
						}, 100);
					}
				} else {
					// List all alerts
					$scope.alertList.push.apply($scope.alertList, _list);
				}

				$scope.alertList.ready = true;
			});
		}

		_loadAlerts();
		var _loadInterval = $interval(_loadAlerts, app.time.refreshInterval);
		$scope.$on('$destroy',function(){
			$interval.cancel(_loadInterval);
		});
	});

	// ======================== Alert Detail ========================
	feature.controller('alertDetail', function(PageConfig, Site, $scope, $wrapState, Entities) {
		PageConfig.pageTitle = "Alert Detail";
		PageConfig.lockSite = true;
		PageConfig
			.addNavPath("Alert List", "/common/alertList")
			.addNavPath("Alert Detail");

		$scope.common = common;

		// Query policy
		$scope.alertList = Entities.queryEntity("AlertService", $wrapState.param.filter);
		$scope.alertList._promise.then(function() {
			if($scope.alertList.length === 0) {
				$.dialog({
					title: "OPS!",
					content: "Alert not found!"
				}, function() {
					location.href = "#/common/alertList";
				});
			} else {
				$scope.alert = $scope.alertList[0];
				$scope.alert.rawAlertContext = JSON.stringify($scope.alert.alertContext, null, "\t");
				Site.current(Site.find($scope.alert.tags.site));
				console.log($scope.alert);
			}
		});

		// UI
		$scope.getMessageTime = function(alert) {
			var _time = common.getValueByPath(alert, "alertContext.timestamp");
			return Number(_time);
		};
	});
})();