var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { BaseEngine, RegisterForStartup } from "@memberjunction/core";
import { UUIDsEqual } from "@memberjunction/global";
/**
 * Caching of metadata for queries and related data, with auto-refresh on entity changes.
 * Returns `MJQueryEntityExtended` instances which include child-relationship getters
 * (QueryFields, QueryParameters, etc.) and business logic (UserCanRun, CategoryPath, etc.).
 */
let QueryEngine = class QueryEngine extends BaseEngine {
    constructor() {
        super(...arguments);
        this._queries = [];
        this._categories = [];
        this._fields = [];
        this._parameters = [];
        this._queryEntities = [];
        this._permissions = [];
        this._dependencies = [];
        this._querySQLs = [];
        this._sqlDialects = [];
    }
    /**
     * Returns the global instance of the class. This is a singleton class, so there is only one instance of it in the application.
     * Do not directly create new instances of it, always use this method to get the instance.
     */
    static get Instance() {
        return super.getInstance();
    }
    async Config(forceRefresh, contextUser, provider) {
        const configs = [
            { Type: 'entity', EntityName: 'MJ: Queries', PropertyName: '_queries', CacheLocal: true },
            { Type: 'entity', EntityName: 'MJ: Query Categories', PropertyName: '_categories', CacheLocal: true },
            { Type: 'entity', EntityName: 'MJ: Query Fields', PropertyName: '_fields', CacheLocal: true },
            { Type: 'entity', EntityName: 'MJ: Query Parameters', PropertyName: '_parameters', CacheLocal: true },
            { Type: 'entity', EntityName: 'MJ: Query Entities', PropertyName: '_queryEntities', CacheLocal: true },
            { Type: 'entity', EntityName: 'MJ: Query Permissions', PropertyName: '_permissions', CacheLocal: true },
            { Type: 'entity', EntityName: 'MJ: Query Dependencies', PropertyName: '_dependencies', CacheLocal: true },
            { Type: 'entity', EntityName: 'MJ: Query SQLs', PropertyName: '_querySQLs', CacheLocal: true },
            { Type: 'entity', EntityName: 'MJ: SQL Dialects', PropertyName: '_sqlDialects', CacheLocal: true },
        ];
        await this.Load(configs, provider, forceRefresh, contextUser);
    }
    // --- Public getters ---
    /** All queries in the system */
    get Queries() {
        return this.GetConfigData('_queries');
    }
    /** All query categories */
    get Categories() {
        return this.GetConfigData('_categories');
    }
    /** Alias for `Categories` — matches IMetadataProvider naming convention */
    get QueryCategories() {
        return this.GetConfigData('_categories');
    }
    /** All query field definitions */
    get Fields() {
        return this.GetConfigData('_fields');
    }
    /** Alias for `Fields` — matches IMetadataProvider naming convention */
    get QueryFields() {
        return this.GetConfigData('_fields');
    }
    /** All query parameter definitions */
    get Parameters() {
        return this.GetConfigData('_parameters');
    }
    /** Alias for `Parameters` — matches IMetadataProvider naming convention */
    get QueryParameters() {
        return this.GetConfigData('_parameters');
    }
    /** All query-to-entity relationship mappings */
    get QueryEntities() {
        return this.GetConfigData('_queryEntities');
    }
    /** All query permission records */
    get Permissions() {
        return this.GetConfigData('_permissions');
    }
    /** Alias for `Permissions` — matches IMetadataProvider naming convention */
    get QueryPermissions() {
        return this.GetConfigData('_permissions');
    }
    /** All query dependency records (composition references) */
    get Dependencies() {
        return this.GetConfigData('_dependencies');
    }
    /** Alias for `Dependencies` — matches IMetadataProvider naming convention */
    get QueryDependencies() {
        return this.GetConfigData('_dependencies');
    }
    /** All query SQL dialect-specific entries */
    get QuerySQLs() {
        return this.GetConfigData('_querySQLs');
    }
    /** All SQL dialect definitions */
    get SQLDialects() {
        return this.GetConfigData('_sqlDialects');
    }
    // --- Convenience helpers ---
    /** Returns only queries with Status === 'Approved' */
    get ApprovedQueries() {
        return this._queries.filter(q => q.Status === 'Approved');
    }
    /** Find a query by its ID */
    FindQueryByID(id) {
        if (!id)
            return undefined;
        const lower = id.trim().toLowerCase();
        return this._queries.find(q => q.ID.trim().toLowerCase() === lower);
    }
    /** Find a query by name, optionally scoped to a category */
    FindQueryByName(name, categoryId) {
        if (!name)
            return undefined;
        const lowerName = name.trim().toLowerCase();
        return this._queries.find(q => {
            const nameMatch = q.Name.trim().toLowerCase() === lowerName;
            if (!nameMatch)
                return false;
            if (categoryId)
                return q.CategoryID?.trim().toLowerCase() === categoryId.trim().toLowerCase();
            return true;
        });
    }
    /** Get all field definitions for a specific query */
    GetQueryFields(queryId) {
        return this._fields.filter(f => UUIDsEqual(f.QueryID, queryId));
    }
    /** Get all parameter definitions for a specific query */
    GetQueryParameters(queryId) {
        return this._parameters.filter(p => UUIDsEqual(p.QueryID, queryId));
    }
    /** Get all permission records for a specific query */
    GetQueryPermissions(queryId) {
        return this._permissions.filter(p => UUIDsEqual(p.QueryID, queryId));
    }
    /** Get all queries belonging to a specific category */
    GetQueriesByCategory(categoryId) {
        return this._queries.filter(q => UUIDsEqual(q.CategoryID, categoryId));
    }
    /** Find a category by name (case-insensitive) */
    FindCategory(name) {
        if (!name)
            return undefined;
        const lower = name.trim().toLowerCase();
        return this._categories.find(c => c.Name.trim().toLowerCase() === lower);
    }
};
QueryEngine = __decorate([
    RegisterForStartup()
], QueryEngine);
export { QueryEngine };
//# sourceMappingURL=QueryEngine.js.map