import { coerceBoolean } from '@angular-ru/cdk/coercion';
import { isNotNil } from '@angular-ru/cdk/utils';

function AttributeBoolean() {
    return function (prototype, key) {
        const descriptor = Object.getOwnPropertyDescriptor(prototype, key);
        const uniqueRefKey = Symbol(`It's boolean attribute`);
        return {
            set(value) {
                var _a;
                this[uniqueRefKey] = coerceBoolean(value);
                (_a = descriptor === null || descriptor === void 0 ? void 0 : descriptor.set) === null || _a === void 0 ? void 0 : _a.call(this, this[uniqueRefKey]);
            },
            get() {
                var _a;
                // eslint-disable-next-line @typescript-eslint/unbound-method
                return isNotNil(descriptor === null || descriptor === void 0 ? void 0 : descriptor.get) ? descriptor === null || descriptor === void 0 ? void 0 : descriptor.get.call(this) : (_a = this[uniqueRefKey]) !== null && _a !== void 0 ? _a : false;
            }
        };
    };
}

/**
 * @internal
 */
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type,max-lines-per-function
function boundMethod(target, key, descriptor) {
    let fn = descriptor.value;
    if (typeof fn !== 'function') {
        throw new TypeError(`@boundMethod decorator can only be applied to methods not: ${typeof fn}`);
    }
    // In IE11 calling Object.defineProperty has a side-effect of evaluating the
    // getter for the property which is being replaced. This causes infinite
    // recursion and an "Out of stack space" error.
    let definingProperty = false;
    return {
        configurable: true,
        // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
        get() {
            // eslint-disable-next-line no-prototype-builtins
            if (definingProperty || this === target.prototype || this.hasOwnProperty(key) || typeof fn !== 'function') {
                return fn;
            }
            const boundFn = fn.bind(this);
            definingProperty = true;
            Object.defineProperty(this, key, {
                configurable: true,
                // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
                get() {
                    return boundFn;
                },
                // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
                set(value) {
                    fn = value;
                    delete this[key];
                }
            });
            definingProperty = false;
            return boundFn;
        },
        // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
        set(value) {
            fn = value;
        }
    };
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,@typescript-eslint/explicit-function-return-type,max-lines-per-function
function BoundClass(target) {
    // (Using reflect to get all keys including symbols)
    let keys;
    // Use Reflect if exists
    if (typeof Reflect !== 'undefined' && typeof Reflect.ownKeys === 'function') {
        keys = Reflect.ownKeys(target.prototype);
    }
    else {
        keys = Object.getOwnPropertyNames(target.prototype);
        // Use symbols if support is provided
        if (typeof Object.getOwnPropertySymbols === 'function') {
            keys = keys.concat(Object.getOwnPropertySymbols(target.prototype));
        }
    }
    keys.forEach((key) => {
        // Ignore special case target method
        if (key === 'constructor') {
            return;
        }
        const descriptor = Object.getOwnPropertyDescriptor(target.prototype, key);
        // Only methods need binding
        if (typeof (descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) === 'function') {
            Object.defineProperty(target.prototype, key, boundMethod(target, key, descriptor));
        }
    });
    return target;
}

/**
 * Generated bundle index. Do not edit.
 */

export { AttributeBoolean, BoundClass };
//# sourceMappingURL=angular-ru-cdk-decorators.js.map
