import { inject } from '@angular/core';
import { isBlank, isType } from '@jscrpt/common';
import { DEFAULT_RELATIONS_COMPONENTS_EXTRACTOR, RELATIONS_COMPONENTS_LOADER_PROVIDER } from './providers';
import { CodeExecutor, RelationsChangeDetector, RelationsComponentManager, RelationsDebugger, RelationsManager, RelationsProcessor } from '../services';
import { RELATIONS_DEBUGGER_TYPE } from './tokens';
//TODO: skip init as constant
//TODO: assigned as constant
/**
 * Checks whether data is relations component def
 * @param data - Data to be checked
 */
export const isRelationsComponentDef = function (data) {
    //type is required and must be type
    if (isBlank(data === null || data === void 0 ? void 0 : data.data) || !isType(data.data)) {
        return false;
    }
    return true;
};
/**
 * Provides relations debugger
 */
export function provideRelationsDebugger() {
    return ngRelationsDebugger ?
        [
            {
                provide: RelationsDebugger,
                useFactory: () => {
                    const relationsDebuggerType = inject(RELATIONS_DEBUGGER_TYPE, { optional: true });
                    if (!relationsDebuggerType) {
                        throw new Error('Please provide RelationsDebugger implementation type! Use "provideRelationsDebuggerImplementation() from @anglr/dynamic/relations-debugger"');
                    }
                    return new relationsDebuggerType();
                },
            }
        ] :
        [];
}
/**
 * Default providers for relations subpackage
 */
export function provideRelations() {
    return [
        DEFAULT_RELATIONS_COMPONENTS_EXTRACTOR,
        RELATIONS_COMPONENTS_LOADER_PROVIDER,
        RelationsComponentManager,
        RelationsManager,
        RelationsProcessor,
        RelationsChangeDetector,
        ...provideRelationsDebugger(),
        CodeExecutor,
    ];
}
/**
 * Defines skip initial data transfer for relations for specified property
 * @param object - Object which will have this new property defined
 * @param name - Name of property for which is skip init defined
 */
export function defineSkipInitProp(object, name) {
    const propName = `${name}SkipInit`;
    if (!Reflect.has(object, propName)) {
        Object.defineProperty(object, propName, {
            value: true,
        });
    }
}
/**
 * Tests whether there is skip init defined for property
 * @param object - Object containg skip init property to be tested
 * @param name - Name of property for which should be skip init defined
 * @returns
 */
export function isSkipInit(object, name) {
    return object[`${name}SkipInit`];
}
/**
 * Defines indication that property was at least once assigned for specified property
 * @param object - Object which will have this new property defined
 * @param name - Name of property for which is assigned defined
 */
export function defineAssignedProp(object, name) {
    const propName = `${name}Assigned`;
    if (!Reflect.has(object, propName)) {
        Object.defineProperty(object, propName, {
            value: true,
        });
    }
}
/**
 * Tests whether there is assigned defined for property
 * @param object - Object containg assigned property to be tested
 * @param name - Name of property for which should be assigned defined
 * @returns
 */
export function isAssigned(object, name) {
    return object[`${name}Assigned`];
}
//# sourceMappingURL=utils.js.map