import { h } from '@stencil/core';
import { Css, PermissionsService } from '@ema/core';
import { Ability } from "@casl/ability";
export class Permission {
    // @Prop() rolesOnly: string;
    // @Prop() rolesExcept: string;
    constructor() {
        this.roles = ['ANONYMOUS'];
        this.rules = [];
        this.can = '["read"]';
        this.subject = 'all';
        this.permissions = PermissionsService.instance;
        this.rules = this.permissions.rules;
        addEventListener('permissionsRulesChange', (event) => {
            if (!this.isolate) {
                this.render();
            }
        });
    }
    componentDidLoad() {
        this.displayDefault = Css.getStyle('display', this.el);
        this.parsePermissions();
    }
    componentDidUpdate() {
        this.parsePermissions();
    }
    componentDidUnload() {
        // todo: remove event listener
        // removeAllListeners()
    }
    async setPermissionService(instance) {
        this.permissions = instance;
        this.rules = [...this.permissions.rules];
    }
    async getRules() {
        return this.rules;
    }
    async setRules(rules, replace = true) {
        if (replace === true) {
            this.rules = [...rules];
        }
        else {
            this.rules = [...this.rules, ...rules];
        }
    }
    async update() {
        this.render();
    }
    parsePermissions() {
        if (!this.ability) {
            return;
        }
        this.el.style.display = this.displayDefault;
        this.canArray.forEach((action) => {
            if (!this.ability.can(action, this.subject)) {
                this.el.style.display = 'none';
                //this.el.removeChild(this.el.firstChild);
            }
        });
        // todo:
        // this.cannotArray.forEach((action) => {
        //     if(!this.ability.cannot(action, this.subject)) {
        //         this.el.style.display = 'none';
        //         //this.el.removeChild(this.el.firstChild);
        //     }
        // });
    }
    onPermissionsRulesChange() {
        if (!this.isolate) {
            this.render();
        }
    }
    render() {
        if (this.rulesJson) {
            this.rules = JSON.parse(this.rulesJson);
        }
        if (this.rules.length) {
            this.rules = [...this.permissions.rules];
            this.ability = new Ability(this.rules);
        }
        if (this.can) {
            this.canArray = JSON.parse(this.can);
        }
        if (this.cannot) {
            this.cannotArray = JSON.parse(this.cannot);
        }
        // console.log('render: ', this.rules.length);
        return (h("span", null,
            h("slot", null)));
    }
    static get is() { return "ema-permission"; }
    static get properties() { return {
        "can": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "can",
            "reflect": false,
            "defaultValue": "'[\"read\"]'"
        },
        "cannot": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "cannot",
            "reflect": false
        },
        "subject": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "subject",
            "reflect": false,
            "defaultValue": "'all'"
        },
        "conditions": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "conditions",
            "reflect": false
        },
        "isolate": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "isolate",
            "reflect": false
        },
        "rulesJson": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "rules-json",
            "reflect": false
        }
    }; }
    static get states() { return {
        "rules": {}
    }; }
    static get methods() { return {
        "setPermissionService": {
            "complexType": {
                "signature": "(instance: any) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        },
        "getRules": {
            "complexType": {
                "signature": "() => Promise<any[]>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<any[]>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        },
        "setRules": {
            "complexType": {
                "signature": "(rules: any[], replace?: boolean) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }, {
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        },
        "update": {
            "complexType": {
                "signature": "() => Promise<void>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        }
    }; }
    static get elementRef() { return "el"; }
}
