var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
// tslint:disable-next-line:max-file-line-count
import { Injectable } from '@angular/core';
import { RequestMethod } from '@angular/http';
import { Observable, BehaviorSubject } from 'rxjs/Rx';
import { ApiRoot } from 'dotcms-js/dotcms-js';
import { ServerSideFieldModel, ServerSideTypeModel } from './ServerSideFieldModel';
import { CoreWebService } from 'dotcms-js/dotcms-js';
import { SiteService } from 'dotcms-js/dotcms-js';
import { Subject } from 'rxjs/Subject';
import { I18nService } from './system/locale/I18n';
export var RULE_CREATE = 'RULE_CREATE';
export var RULE_DELETE = 'RULE_DELETE';
export var RULE_UPDATE_NAME = 'RULE_UPDATE_NAME';
export var RULE_UPDATE_ENABLED_STATE = 'RULE_UPDATE_ENABLED_STATE';
export var V_RULE_UPDATE_EXPANDED_STATE = 'V_RULE_UPDATE_EXPANDED_STATE';
export var RULE_UPDATE_FIRE_ON = 'RULE_UPDATE_FIRE_ON';
export var RULE_RULE_ACTION_CREATE = 'RULE_RULE_ACTION_CREATE';
export var RULE_RULE_ACTION_DELETE = 'RULE_RULE_ACTION_DELETE';
export var RULE_RULE_ACTION_UPDATE_TYPE = 'RULE_RULE_ACTION_UPDATE_TYPE';
export var RULE_RULE_ACTION_UPDATE_PARAMETER = 'RULE_RULE_ACTION_UPDATE_PARAMETER';
export var RULE_CONDITION_GROUP_UPDATE_OPERATOR = 'RULE_CONDITION_GROUP_UPDATE_OPERATOR';
export var RULE_CONDITION_GROUP_DELETE = 'RULE_CONDITION_GROUP_DELETE';
export var RULE_CONDITION_GROUP_CREATE = 'RULE_CONDITION_GROUP_CREATE';
export var RULE_CONDITION_CREATE = 'RULE_CONDITION_CREATE';
export var RULE_CONDITION_DELETE = 'RULE_CONDITION_DELETE';
export var RULE_CONDITION_UPDATE_TYPE = 'RULE_CONDITION_UPDATE_TYPE';
export var RULE_CONDITION_UPDATE_PARAMETER = 'RULE_CONDITION_UPDATE_PARAMETER';
export var RULE_CONDITION_UPDATE_OPERATOR = 'RULE_CONDITION_UPDATE_OPERATOR';
var idCounter = 1000;
// tslint:disable-next-line:only-arrow-functions
export function getNextId() {
    return 'tempId' + ++idCounter;
}
var RuleEngineState = (function () {
    function RuleEngineState() {
        this.showRules = true;
        this.globalError = null;
        this.loading = true;
        this.saving = false;
        this.hasError = false;
        this.filter = '';
        this.deleting = false;
    }
    return RuleEngineState;
}());
export { RuleEngineState };
var ActionModel = (function (_super) {
    __extends(ActionModel, _super);
    function ActionModel(key, type, priority) {
        if (priority === void 0) { priority = 1; }
        var _this = _super.call(this, key, type, priority) || this;
        _this.priority = priority || 1;
        _this.type = type;
        return _this;
    }
    ActionModel.prototype.isValid = function () {
        try {
            return _super.prototype.isValid.call(this);
        }
        catch (e) {
            this.loggerService.error(e);
        }
    };
    return ActionModel;
}(ServerSideFieldModel));
export { ActionModel };
var ConditionModel = (function (_super) {
    __extends(ConditionModel, _super);
    function ConditionModel(iCondition) {
        var _this = _super.call(this, iCondition.id, iCondition._type) || this;
        _this.operator = 'AND';
        _this.conditionlet = iCondition.conditionlet;
        _this.key = iCondition.id;
        _this.priority = iCondition.priority || 1;
        _this.type = iCondition._type;
        _this.operator = iCondition.operator || 'AND';
        return _this;
    }
    ConditionModel.prototype.isValid = function () {
        try {
            return !!this.getParameterValue('comparison') && _super.prototype.isValid.call(this);
        }
        catch (e) {
            this.loggerService.error(e);
        }
    };
    return ConditionModel;
}(ServerSideFieldModel));
export { ConditionModel };
var ConditionGroupModel = (function () {
    function ConditionGroupModel(iGroup) {
        this._conditions = [];
        Object.assign(this, iGroup);
        this.key = iGroup.id;
        this._id = this.key != null ? this.key : getNextId();
        this.conditions = iGroup.conditions || {};
    }
    ConditionGroupModel.prototype.isPersisted = function () {
        return this.key != null;
    };
    ConditionGroupModel.prototype.isValid = function () {
        var valid = this.operator && (this.operator === 'AND' || this.operator === 'OR');
        return valid;
    };
    return ConditionGroupModel;
}());
export { ConditionGroupModel };
var RuleModel = (function () {
    function RuleModel(iRule) {
        var _this = this;
        this.enabled = false;
        this.conditionGroups = {};
        this.ruleActions = {};
        this._expanded = false;
        this._conditionGroups = [];
        this._ruleActions = [];
        this._saved = true;
        this._saving = false;
        this._deleting = true;
        Object.assign(this, iRule);
        this.key = iRule.id;
        this._id = this.key != null ? this.key : getNextId();
        var conGroups = Object.keys(iRule.conditionGroups || {});
        conGroups.forEach(function (groupId) {
            var g = _this.conditionGroups[groupId];
            var mg = new ConditionGroupModel(Object.assign({ id: groupId }, g));
            _this.conditionGroups[groupId] = mg;
            _this._conditionGroups.push(mg);
        });
    }
    RuleModel.prototype.isPersisted = function () {
        return this.key != null;
    };
    RuleModel.prototype.isValid = function () {
        var valid = !!this.name;
        valid = valid && this.name.trim().length > 0;
        return valid;
    };
    return RuleModel;
}());
export { RuleModel };
export var DEFAULT_RULE = {
    _conditionGroups: [],
    _expanded: false,
    _id: -1 + '',
    _ruleActions: [],
    conditionGroups: {},
    enabled: false,
    fireOn: 'EVERY_PAGE',
    name: null,
    priority: 1,
    ruleActions: {}
};
var RuleService = (function () {
    function RuleService(_apiRoot, _resources, siteService, coreWebService) {
        var _this = this;
        this._apiRoot = _apiRoot;
        this._resources = _resources;
        this.siteService = siteService;
        this.coreWebService = coreWebService;
        this.ruleActionTypes$ = new BehaviorSubject([]);
        this.conditionTypes$ = new BehaviorSubject([]);
        this._ruleActionTypes = {};
        this._conditionTypes = {};
        this._rules$ = new Subject();
        // tslint:disable-next-line:no-unused-variable
        this._ruleActions = {};
        // tslint:disable-next-line:no-unused-variable
        this._conditions = {};
        this._ruleActionTypesAry = [];
        this._conditionTypesAry = [];
        this._errors$ = new Subject();
        this._rulesEndpointUrl = "/ruleengine/rules";
        this._actionsEndpointUrl = "/ruleengine/actions";
        this._conditionTypesEndpointUrl = this._apiRoot
            .baseUrl + "api/v1/system/ruleengine/conditionlets";
        this._ruleActionTypesEndpointUrl = this._apiRoot
            .baseUrl + "api/v1/system/ruleengine/actionlets";
        this._preCacheCommonResources(_resources);
        this.loadActionTypes().subscribe(function (types) {
            _this.ruleActionTypes$.next(types);
        }, function (err) {
            _this._errors$.next(err);
        });
        this.loadConditionTypes().subscribe(function (types) {
            _this.conditionTypes$.next(types);
        }, function (err) {
            _this._errors$.next(err);
        });
        this.siteService.switchSite$.subscribe(function (site) {
            var siteId = _this.loadRulesSiteId();
            if (siteId === site.identifier) {
                _this.sendLoadRulesRequest(site.identifier);
            }
        });
    }
    RuleService.fromServerRulesTransformFn = function (ruleMap) {
        return Object.keys(ruleMap).map(function (id) {
            var r = ruleMap[id];
            r.id = id;
            return new RuleModel(r);
        });
    };
    RuleService.fromClientRuleTransformFn = function (rule) {
        var sendRule = Object.assign({}, DEFAULT_RULE, rule);
        sendRule.key = rule.key;
        delete sendRule.id;
        sendRule.conditionGroups = {};
        sendRule._conditionGroups.forEach(function (conditionGroup) {
            if (conditionGroup.key) {
                var sendGroup_1 = {
                    conditions: {},
                    operator: conditionGroup.operator,
                    priority: conditionGroup.priority
                };
                conditionGroup._conditions.forEach(function (condition) {
                    sendGroup_1.conditions[condition.key] = true;
                });
                sendRule.conditionGroups[conditionGroup.key] = sendGroup_1;
            }
        });
        RuleService.removeMeta(sendRule);
        return sendRule;
    };
    RuleService.removeMeta = function (entity) {
        Object.keys(entity).forEach(function (key) {
            if (key[0] === '_') {
                delete entity[key];
            }
        });
    };
    RuleService.alphaSort = function (key) {
        return function (a, b) {
            var x;
            if (a[key] > b[key]) {
                x = 1;
            }
            else if (a[key] < b[key]) {
                x = -1;
            }
            else {
                x = 0;
            }
            return x;
        };
    };
    RuleService.fromServerServersideTypesTransformFn = function (typesMap) {
        var types = Object.keys(typesMap).map(function (key) {
            var json = typesMap[key];
            json.key = key;
            return ServerSideTypeModel.fromJson(json);
        });
        return types.filter(function (type) { return type.key !== 'CountRulesActionlet'; });
    };
    RuleService.prototype.createRule = function (body) {
        var siteId = this.loadRulesSiteId();
        return this.coreWebService
            .request({
            body: RuleService.fromClientRuleTransformFn(body),
            method: RequestMethod.Post,
            url: this._apiRoot.baseUrl + "api/v1/sites/" + siteId + this._rulesEndpointUrl
        })
            .map(function (result) {
            body.key = result['id']; // @todo:ggranum type the POST result correctly.
            return Object.assign({}, DEFAULT_RULE, body, result);
        });
    };
    RuleService.prototype.deleteRule = function (ruleId) {
        var siteId = this.loadRulesSiteId();
        return this.coreWebService
            .request({
            method: RequestMethod.Delete,
            url: this._apiRoot.baseUrl + "api/v1/sites/" + siteId + this
                ._rulesEndpointUrl + "/" + ruleId
        })
            .map(function (result) {
            return { success: true };
        });
    };
    RuleService.prototype.loadRules = function () {
        return this._rules$.asObservable();
    };
    RuleService.prototype.requestRules = function (siteId) {
        if (siteId) {
            this.sendLoadRulesRequest(siteId);
        }
        else if (this.siteService.currentSite) {
            this.sendLoadRulesRequest(this.siteService.currentSite.identifier);
        }
    };
    Object.defineProperty(RuleService.prototype, "rules", {
        get: function () {
            return this._rules;
        },
        enumerable: true,
        configurable: true
    });
    RuleService.prototype.loadRule = function (id) {
        var siteId = this.loadRulesSiteId();
        return this.coreWebService
            .request({
            method: RequestMethod.Get,
            url: this._apiRoot.baseUrl + "api/v1/sites/" + siteId + this._rulesEndpointUrl + "/" + id
        })
            .map(function (result) {
            return Object.assign({ key: id }, DEFAULT_RULE, result);
        });
    };
    RuleService.prototype.updateRule = function (id, rule) {
        var result;
        var siteId = this.loadRulesSiteId();
        if (!id) {
            result = this.createRule(rule);
        }
        else {
            result = this.coreWebService
                .request({
                body: RuleService.fromClientRuleTransformFn(rule),
                method: RequestMethod.Put,
                url: this._apiRoot.baseUrl + "api/v1/sites/" + siteId + this
                    ._rulesEndpointUrl + "/" + id
            })
                .map(function (res) {
                var r = Object.assign({}, DEFAULT_RULE, res);
                r.id = id;
                return r;
            });
        }
        return result;
    };
    RuleService.prototype.getConditionTypes = function () {
        return this.coreWebService
            .request({
            method: RequestMethod.Get,
            url: this._conditionTypesEndpointUrl
        })
            .map(RuleService.fromServerServersideTypesTransformFn);
    };
    RuleService.prototype.getRuleActionTypes = function () {
        return this.coreWebService
            .request({
            method: RequestMethod.Get,
            url: this._ruleActionTypesEndpointUrl
        })
            .map(RuleService.fromServerServersideTypesTransformFn);
    };
    RuleService.prototype._doLoadRuleActionTypes = function () {
        return this.coreWebService
            .request({
            method: RequestMethod.Get,
            url: this._ruleActionTypesEndpointUrl
        })
            .map(RuleService.fromServerServersideTypesTransformFn);
    };
    RuleService.prototype._doLoadConditionTypes = function () {
        return this.coreWebService
            .request({
            method: RequestMethod.Get,
            url: this._conditionTypesEndpointUrl
        })
            .map(RuleService.fromServerServersideTypesTransformFn);
    };
    RuleService.prototype._preCacheCommonResources = function (resources) {
        resources.get('api.sites.ruleengine').subscribe(function (rsrc) { });
        resources.get('api.ruleengine.system').subscribe(function (rsrc) { });
        resources.get('api.system.ruleengine').subscribe(function (rsrc) { });
    };
    RuleService.prototype.sendLoadRulesRequest = function (siteId) {
        var _this = this;
        this.coreWebService
            .request({
            method: RequestMethod.Get,
            url: this._apiRoot.baseUrl + "api/v1/sites/" + siteId + "/ruleengine/rules"
        })
            .subscribe(function (ruleMap) {
            _this._rules = RuleService.fromServerRulesTransformFn(ruleMap);
            _this._rules$.next(_this.rules);
            return RuleService.fromServerRulesTransformFn(ruleMap);
        }, function (err) {
            _this._errors$.next(err);
        });
    };
    RuleService.prototype.loadActionTypes = function () {
        var obs;
        if (this._ruleActionTypesAry.length) {
            obs = Observable.from(this._ruleActionTypesAry);
        }
        else {
            return this.actionAndConditionTypeLoader(this._doLoadRuleActionTypes(), this._ruleActionTypes);
        }
        return obs;
    };
    RuleService.prototype.actionAndConditionTypeLoader = function (requestObserver, typeMap) {
        var _this = this;
        return requestObserver.flatMap(function (types) {
            return Observable.from(types)
                .flatMap(function (type) {
                return _this._resources
                    .get(type.i18nKey + '.name', type.i18nKey)
                    .map(function (label) {
                    type._opt = { value: type.key, label: label };
                    return type;
                });
            })
                .reduce(function (types, type) {
                types.push(type);
                return types;
            }, [])
                .do(function (typ) {
                typ = typ.sort(function (typeA, typeB) {
                    return typeA._opt.label.localeCompare(typeB._opt.label);
                });
                typ.forEach(function (type) {
                    typeMap[type.key] = type;
                });
                return typ;
            });
        });
    };
    RuleService.prototype.loadConditionTypes = function () {
        var obs;
        if (this._conditionTypesAry.length) {
            obs = Observable.from(this._conditionTypesAry);
        }
        else {
            return this.actionAndConditionTypeLoader(this._doLoadConditionTypes(), this._conditionTypes);
        }
        return obs;
    };
    /**
   * Return the Site Id or Page Id for the rules operations.
   * First will check if the realmId parameter is included in the url.
   * If not then search for the current site Id.
   * @returns string
   */
    RuleService.prototype.loadRulesSiteId = function () {
        var siteId;
        var query = document.location.search.substring(1);
        if (query === '') {
            if (document.location.hash.indexOf('?') >= 0) {
                query = document.location.hash.substr(document.location.hash.indexOf('?') + 1);
            }
        }
        /**
     * Search if the realId parameter is set
     */
        siteId = ApiRoot.parseQueryParam(query, 'realmId');
        if (!siteId) {
            /**
       * If the realmId parameter is not set get the current Site Id
       */
            siteId = "" + this.siteService.currentSite.identifier;
        }
        return siteId;
    };
    return RuleService;
}());
export { RuleService };
RuleService.decorators = [
    { type: Injectable },
];
/** @nocollapse */
RuleService.ctorParameters = function () { return [
    { type: ApiRoot, },
    { type: I18nService, },
    { type: SiteService, },
    { type: CoreWebService, },
]; };
//# sourceMappingURL=Rule.js.map