import { InjectFlags, ɵɵdirectiveInject, ɵɵinject, INJECTOR, ɵNG_COMP_DEF, ɵNG_DIR_DEF, ɵNG_PIPE_DEF, ɵNG_PROV_DEF, ɵNG_INJ_DEF } from '@angular/core';
import { isString } from '@angular-ru/cdk/string';
import { isNil, isNotNil, isTrue } from '@angular-ru/cdk/utils';

/* eslint-disable no-redeclare */
function wrapperForInject(wrap, token, flags) {
    if (InjectFlags.Optional) {
        try {
            return wrap(token, flags);
        }
        catch (_a) {
            return null;
        }
    }
    else {
        return flags ? wrap(token, flags) : wrap(token);
    }
}
function directiveInject(token, flags) {
    return wrapperForInject(ɵɵdirectiveInject, token, flags);
}
function inject(token, flags) {
    return wrapperForInject(ɵɵinject, token, flags);
}

const NG_FACTORY_DEF = 'ɵfac';
const PATCHER_KEY = 'NG_RU_PATCHER';
function useInjector(constructor, effectFunction) {
    const deferWrapping = isNil(getOwnDefinitionOfClass(constructor));
    if (deferWrapping) {
        Promise.resolve()
            .then(() => wrapFactory(constructor, effectFunction))
            .catch((error) => console.error(error));
    }
    else {
        wrapFactory(constructor, effectFunction);
    }
}
function wrapFactory(constructor, effectFunction) {
    const definition = getOwnDefinitionOfClass(constructor);
    if (isNil(definition)) {
        throw new Error('Class with useInjector in decorator must be Injectable');
    }
    const ngFactoryNotWrapped = getPatcherOfClass(constructor);
    if (isNil(ngFactoryNotWrapped)) {
        definition.factory = generateFactoryWrapper(constructor, definition);
        insertFactoryWrapper(constructor, definition.factory);
    }
    insertPatcher(constructor, effectFunction);
}
function generateFactoryWrapper(constructor, definition) {
    var _a;
    const ngFactory = (_a = definition.factory) !== null && _a !== void 0 ? _a : getNgFactoryOfClass(constructor);
    return function (...args) {
        const instance = ngFactory(...args);
        const patch = getPatcherOfClass(constructor);
        if (isNotNil(patch)) {
            const injector = ɵɵdirectiveInject(INJECTOR);
            patch(injector, instance);
        }
        return instance;
    };
}
function insertFactoryWrapper(constructor, factory) {
    Object.defineProperty(constructor, NG_FACTORY_DEF, {
        configurable: true,
        writable: true,
        value: factory
    });
}
function insertPatcher(constructor, effectFunction) {
    const previousPatcher = getPatcherOfClass(constructor);
    /**
     * Note: don't use hasOwnProperty,
     * because we need find reference on PATCHER_KEY in prototypes chain
     */
    const patchSuper = constructor[PATCHER_KEY];
    Object.defineProperty(constructor, PATCHER_KEY, {
        configurable: true,
        writable: true,
        value(injector, instance) {
            if (isNotNil(previousPatcher)) {
                previousPatcher(injector, instance);
            }
            else if (isNotNil(patchSuper)) {
                patchSuper(injector, instance);
            }
            effectFunction(injector, instance);
        }
    });
}
function getOwnDefinitionOfClass(constructor) {
    const definedProperty = [
        ɵNG_COMP_DEF,
        ɵNG_DIR_DEF,
        ɵNG_PIPE_DEF,
        ɵNG_PROV_DEF,
        ɵNG_INJ_DEF //   for module
    ].find((property) => constructor.hasOwnProperty(property));
    return isString(definedProperty) ? constructor[definedProperty] : undefined;
}
function getNgFactoryOfClass(constructor) {
    if (isTrue(constructor === null || constructor === void 0 ? void 0 : constructor.hasOwnProperty(NG_FACTORY_DEF))) {
        return constructor[NG_FACTORY_DEF];
    }
    else {
        return undefined;
    }
}
function getPatcherOfClass(constructor) {
    if (isTrue(constructor === null || constructor === void 0 ? void 0 : constructor.hasOwnProperty(PATCHER_KEY))) {
        return constructor[PATCHER_KEY];
    }
    else {
        return undefined;
    }
}

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

export { directiveInject, inject, useInjector };
//# sourceMappingURL=angular-ru-cdk-ivy.js.map
