/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { DataProduct, ModelAccessPointGroup, NativeModelExecutionContext, CORE_PURE_PATH, PackageableRuntime, resolveUsableDataProductClasses, LakehouseRuntime, SimpleFunctionExpression, InstanceValue, Multiplicity, extractElementNameFromPath, SUPPORTED_FUNCTIONS, PackageableElementExplicitReference, resolveDataProductExecutionState, RuntimePointer, QueryDataProductNativeExecutionContext, QueryDataProductModelAccessExecutionContext, QueryDataProductLakehouseExecutionContext, LakehouseAccessPoint, buildRawLambdaFromLambdaFunction, DataProductAccessor, RelationType, RelationColumn, GenericType, GenericTypeExplicitReference, findLakehouseAccessPointGroup, V1_buildRelationTypeFromAccessPointImplementation, LegendSDLC, DataProductAccessType, } from '@finos/legend-graph';
import { QueryBuilderState } from '../../QueryBuilderState.js';
import {} from '@finos/legend-application';
import { renderDataProductQueryBuilderSetupPanelContent } from '../../../components/workflows/DataProductQueryBuilder.js';
import { ActionState, assertErrorThrown, filterByType, guaranteeNonNullable, } from '@finos/legend-shared';
import { action, computed, flow, makeObservable, observable } from 'mobx';
import { DepotEntityWithOrigin, } from '@finos/legend-storage';
import { compareLabelFn } from '@finos/legend-art';
import { QueryBuilderEmbeddedFromExecutionContextState } from '../../QueryBuilderExecutionContextState.js';
import { buildLambdaFunction } from '../../QueryBuilderValueSpecificationBuilder.js';
export const resolveDataProductAccessor = (dataProduct, accessPoint, graph, artifact, relationMetadata) => {
    if (artifact) {
        const artifactGroup = artifact.accessPointGroups.find((apg) => apg.accessPointImplementations.some((apImpl) => apImpl.id === accessPoint.id));
        const artifactImpl = artifactGroup?.accessPointImplementations.find((apImpl) => apImpl.id === accessPoint.id);
        if (artifactImpl) {
            const builtRelationType = V1_buildRelationTypeFromAccessPointImplementation(artifactImpl, graph, accessPoint.title ?? accessPoint.id);
            if (builtRelationType) {
                return new DataProductAccessor(dataProduct.path, artifactGroup?.id, accessPoint.id, builtRelationType, dataProduct);
            }
        }
    }
    const relationType = new RelationType(accessPoint.title ?? accessPoint.id);
    if (relationMetadata) {
        relationType.columns = relationMetadata.columns.map((col) => new RelationColumn(col.name, GenericTypeExplicitReference.create(new GenericType(graph.getType(col.type)))));
    }
    const groupResult = findLakehouseAccessPointGroup(dataProduct, accessPoint.id);
    return new DataProductAccessor(dataProduct.path, groupResult?.group.id, accessPoint.id, relationType, dataProduct);
};
export const buildDataProductOption = (value) => ({
    label: value.name,
    value,
});
export const buildExecOptions = (val) => {
    return {
        label: val.key,
        value: val,
    };
};
export const buildModelAccessPointGroupOption = (value) => ({
    label: value.title ?? value.id,
    value,
});
export class DataProductExecutionState {
    queryBuilderState;
    exectionValue;
    constructor(executionState, queryBuilderState) {
        this.queryBuilderState = queryBuilderState;
        this.exectionValue = executionState;
    }
    get showRuntimeOptions() {
        return false;
    }
    get selectedOption() {
        return {
            label: this.label,
            value: this.exectionValue,
        };
    }
}
export class NativeModelDataProductExecutionState extends DataProductExecutionState {
    nativeModelAccess;
    constructor(executionState, queryBuilderState) {
        super(executionState, queryBuilderState);
        this.nativeModelAccess = executionState.__owner;
    }
    get label() {
        return this.exectionValue.key;
    }
    get mapping() {
        return this.exectionValue.mapping.value;
    }
    get featuredElements() {
        return this.nativeModelAccess.featuredElements;
    }
}
export class ModelAccessPointDataProductExecutionState extends DataProductExecutionState {
    selectedRuntime;
    adhocRuntime = false;
    constructor(executionState, queryBuilderState) {
        super(executionState, queryBuilderState);
        makeObservable(this, {
            selectedRuntime: observable,
            adhocRuntime: observable,
            compatibleRuntimes: computed,
            showRuntimeOptions: computed,
            changeSelectedRuntime: action,
            withAdhocRuntime: action,
        });
        this.selectedRuntime = this.compatibleRuntimes[0];
    }
    changeSelectedRuntime(val) {
        this.selectedRuntime = val;
        this.queryBuilderState.changeRuntime(new RuntimePointer(PackageableElementExplicitReference.create(val)));
    }
    withAdhocRuntime() {
        this.adhocRuntime = true;
        return this;
    }
    get label() {
        return this.exectionValue.title ?? this.exectionValue.id;
    }
    get mapping() {
        return this.exectionValue.mapping.value;
    }
    get featuredElements() {
        return this.exectionValue.featuredElements;
    }
    get showRuntimeOptions() {
        return this.compatibleRuntimes.length > 1;
    }
    get compatibleRuntimes() {
        return this.queryBuilderState.graphManagerState.usableRuntimes.filter((runtime) => runtime.runtimeValue instanceof LakehouseRuntime);
    }
}
export class LakehouseDataProductExecutionState extends DataProductExecutionState {
    selectedRuntime;
    adhocRuntime = false;
    constructor(executionState, queryBuilderState) {
        super(executionState, queryBuilderState);
        makeObservable(this, {
            withAdhocRuntime: observable,
            selectedRuntime: observable,
            changeSelectedRuntime: action,
            compatibleRuntimes: computed,
            showRuntimeOptions: computed,
        });
        this.selectedRuntime = this.compatibleRuntimes[0];
    }
    changeSelectedRuntime(val) {
        this.selectedRuntime = val;
        this.queryBuilderState.changeRuntime(new RuntimePointer(PackageableElementExplicitReference.create(val)));
    }
    withAdhocRuntime() {
        this.adhocRuntime = true;
        return this;
    }
    get label() {
        return this.exectionValue.title ?? this.exectionValue.id;
    }
    get mapping() {
        return undefined;
    }
    get featuredElements() {
        return undefined;
    }
    get compatibleRuntimes() {
        return this.queryBuilderState.graphManagerState.usableRuntimes.filter((runtime) => runtime.runtimeValue instanceof LakehouseRuntime);
    }
    get showRuntimeOptions() {
        return this.compatibleRuntimes.length > 1;
    }
}
export class DataProductQueryBuilderState extends QueryBuilderState {
    onClassChange;
    onDataProductChange;
    loadDataProductModelState = ActionState.create();
    dataProduct;
    dataProductArtifact;
    executionState;
    entities;
    mappingToMappingCoverageResult;
    prioritizeEntityFunc;
    TEMPORARY__setupPanelContentRenderer = () => renderDataProductQueryBuilderSetupPanelContent(this);
    constructor(applicationStore, graphManagerState, workflow, dataProduct, artifact, actionConfig, executionState, prioritizeEntityFunc, onDataProductChange, onClassChange, config, sourceInfo) {
        super(applicationStore, graphManagerState, workflow, config, sourceInfo);
        makeObservable(this, {
            dataProduct: observable,
            executionState: observable,
            initWithDataProduct: action,
            handleDataProductChange: action,
            setExecutionState: action,
            selectedDataProductOption: computed,
            isProductLinkable: computed,
            isNativeMode: computed,
            isModelAccessPointGroupMode: computed,
            isLakehouseMode: computed,
            showExecutionContextOptions: computed,
            showModelAccessPointGroupSelector: computed,
            showExecutionIdSelector: computed,
            executionIdOptions: computed,
            selectedExecutionIdOption: computed,
            hasNativeModelAccess: computed,
            hasBothAccessModes: computed,
            showContextSelector: computed,
            allContextOptions: computed,
            selectedContextOption: computed,
            selectedExecOption: computed,
            selectedModelAccessPointGroupOption: computed,
            usableClasses: computed,
            modelAccessPointGroups: computed,
            hasModelAccessPointGroups: computed,
            modelAccessPointGroupOptions: computed,
            activeMapping: computed,
            activeFeaturedElements: computed,
            loadEntities: flow,
            entities: observable,
        });
        // for queries against data product, we always want to default to from
        this.executionContextState =
            new QueryBuilderEmbeddedFromExecutionContextState(this);
        this.workflowState.updateActionConfig(actionConfig);
        this.dataProduct = dataProduct;
        this.dataProductArtifact = artifact;
        this.executionState =
            executionState instanceof NativeModelExecutionContext
                ? new NativeModelDataProductExecutionState(executionState, this)
                : executionState instanceof LakehouseAccessPoint
                    ? new LakehouseDataProductExecutionState(executionState, this)
                    : new ModelAccessPointDataProductExecutionState(executionState, this);
        this.prioritizeEntityFunc = prioritizeEntityFunc;
        this.onDataProductChange = onDataProductChange;
        this.onClassChange = onClassChange;
        // force from.
        this.executionContextState =
            new QueryBuilderEmbeddedFromExecutionContextState(this);
    }
    async prepareAccessForExecution() {
        if (this.executionState instanceof NativeModelDataProductExecutionState) {
            const runtime = this.executionState.exectionValue.runtime;
            if (runtime) {
                this.changeRuntime(new RuntimePointer(runtime));
            }
        }
        else if (this.executionState instanceof
            ModelAccessPointDataProductExecutionState &&
            this.executionState.selectedRuntime) {
            this.changeRuntime(new RuntimePointer(PackageableElementExplicitReference.create(this.executionState.selectedRuntime)));
        }
        else if (this.executionState instanceof LakehouseDataProductExecutionState &&
            this.executionState.selectedRuntime) {
            this.changeRuntime(new RuntimePointer(PackageableElementExplicitReference.create(this.executionState.selectedRuntime)));
        }
    }
    get isProductLinkable() {
        return false;
    }
    get isNativeMode() {
        return this.executionState instanceof NativeModelDataProductExecutionState;
    }
    get isModelAccessPointGroupMode() {
        return (this.executionState instanceof ModelAccessPointDataProductExecutionState);
    }
    get isLakehouseMode() {
        return this.executionState instanceof LakehouseDataProductExecutionState;
    }
    get showExecutionContextOptions() {
        return this.isNativeMode && this.execOptions.length > 1;
    }
    get showModelAccessPointGroupSelector() {
        return (this.isModelAccessPointGroupMode &&
            this.modelAccessPointGroupOptions.length > 1);
    }
    get hasNativeModelAccess() {
        return this.dataProduct.nativeModelAccess !== undefined;
    }
    get hasBothAccessModes() {
        return this.hasModelAccessPointGroups && this.hasNativeModelAccess;
    }
    // showContextSelector / allContextOptions / selectedContextOption are aliases
    // over the upstream ExecutionIdOption API so existing UI code keeps working.
    get showContextSelector() {
        return this.showExecutionIdSelector;
    }
    get allContextOptions() {
        return this.executionIdOptions;
    }
    get selectedContextOption() {
        return this.selectedExecutionIdOption;
    }
    get executionIdOptions() {
        const nativeOptions = (this.dataProduct.nativeModelAccess?.nativeModelExecutionContexts ?? []).map((ctx) => ({
            label: ctx.key,
            tag: 'NATIVE',
            value: ctx,
        }));
        const modelOptions = this.modelAccessPointGroups.map((group) => ({
            label: group.title ?? group.id,
            tag: 'MODEL',
            value: group,
        }));
        const lakehouseOptions = this.dataProduct.accessPointGroups
            .flatMap((group) => group.accessPoints)
            .filter(filterByType(LakehouseAccessPoint))
            .map((ap) => ({
            label: ap.title ?? ap.id,
            tag: 'LAKEHOUSE',
            value: ap,
        }));
        return [...modelOptions, ...lakehouseOptions, ...nativeOptions].sort(compareLabelFn);
    }
    get selectedExecutionIdOption() {
        const state = this.executionState;
        if (state instanceof NativeModelDataProductExecutionState) {
            return {
                label: state.exectionValue.key,
                tag: 'NATIVE',
                value: state.exectionValue,
            };
        }
        else if (state instanceof ModelAccessPointDataProductExecutionState) {
            return {
                label: state.exectionValue.title ?? state.exectionValue.id,
                tag: 'MODEL',
                value: state.exectionValue,
            };
        }
        else if (state instanceof LakehouseDataProductExecutionState) {
            return {
                label: state.exectionValue.title ?? state.exectionValue.id,
                tag: 'LAKEHOUSE',
                value: state.exectionValue,
            };
        }
        return undefined;
    }
    get showExecutionIdSelector() {
        return this.executionIdOptions.length > 1;
    }
    async changeExecutionId(option) {
        const val = option.value;
        if (val === this.executionState.exectionValue) {
            return;
        }
        const switchingToModel = val instanceof ModelAccessPointGroup;
        const switchingToNative = val instanceof NativeModelExecutionContext;
        const wasModeSwitch = (switchingToModel && this.isNativeMode) ||
            (switchingToNative && this.isModelAccessPointGroupMode);
        if (wasModeSwitch) {
            this.changeHistoryState.querySnapshotBuffer = [];
            this.changeHistoryState.pointer = -1;
            this.changeHistoryState.setCurrentQuery(undefined);
        }
        await this.changeExecutionState(val);
        await this.propagateExecutionContextChange();
    }
    get selectedExecOption() {
        return this.executionState instanceof NativeModelDataProductExecutionState
            ? buildExecOptions(this.executionState.exectionValue)
            : undefined;
    }
    get requiresMappingForExecution() {
        if (this.executionState instanceof LakehouseDataProductExecutionState) {
            return false;
        }
        return true;
    }
    get selectedModelAccessPointGroupOption() {
        return this.executionState instanceof
            ModelAccessPointDataProductExecutionState
            ? buildModelAccessPointGroupOption(this.executionState.exectionValue)
            : undefined;
    }
    get usableClasses() {
        const activeMapping = this.activeMapping;
        return activeMapping
            ? resolveUsableDataProductClasses(this.activeFeaturedElements, activeMapping, this.graphManagerState, this.explorerState.mappingModelCoverageAnalysisResult)
            : [];
    }
    buildQueryForPersistence() {
        if (!this.isQuerySupported) {
            return this.buildQuery();
        }
        // Build without embedding execution context in the lambda body.
        // The execution context (dataProductPath, executionKey/accessPointGroupId)
        // is stored separately in query.executionContext via getQueryExecutionContext().
        return buildRawLambdaFromLambdaFunction(buildLambdaFunction(this, {
            skipExecutionContext: true,
            useTypedRelationFunctions: this.isFetchStructureTyped,
        }), this.graphManagerState);
    }
    getQueryExecutionContext() {
        if (this.executionState instanceof NativeModelDataProductExecutionState) {
            const execContext = new QueryDataProductNativeExecutionContext();
            execContext.dataProductPath = this.dataProduct.path;
            execContext.executionKey = this.executionState.exectionValue.key;
            return execContext;
        }
        else if (this.executionState instanceof ModelAccessPointDataProductExecutionState) {
            const execContext = new QueryDataProductModelAccessExecutionContext();
            execContext.dataProductPath = this.dataProduct.path;
            execContext.accessPointGroupId = this.executionState.exectionValue.id;
            return execContext;
        }
        else if (this.executionState instanceof LakehouseDataProductExecutionState) {
            const execContext = new QueryDataProductLakehouseExecutionContext();
            execContext.dataProductPath = this.dataProduct.path;
            execContext.accessGroupId = this.executionState.exectionValue.__owner.id;
            execContext.accessPointId = this.executionState.exectionValue.id;
            return execContext;
        }
        return super.getQueryExecutionContext();
    }
    handleDataProductChange(val) {
        try {
            this.loadDataProductModelState.inProgress();
            const dataProduct = this.graphManagerState.graph.getOwnNullableDataProduct(val.path) ??
                this.graphManagerState.graph.generationModel.getOwnNullableDataProduct(val.path);
            if (dataProduct) {
                this.initWithDataProduct(dataProduct, undefined, undefined);
                this.loadDataProductModelState.pass();
            }
            else if (this.onDataProductChange) {
                // data product not in current graph — trigger full rebuild
                this.onDataProductChange(val).catch((error) => {
                    assertErrorThrown(error);
                    this.applicationStore.notificationService.notifyError(`Failed to change Data Product: ${error.message}`);
                    this.loadDataProductModelState.fail();
                });
            }
            else {
                throw new Error(`Data Product '${val.path}' not found in current graph and no cross-project handler is available`);
            }
        }
        catch (error) {
            assertErrorThrown(error);
            this.applicationStore.notificationService.notifyError(`Failed to change Data Product: ${error.message}`);
            this.loadDataProductModelState.fail();
        }
    }
    initWithDataProduct(dataProduct, accessor, preResolvedState) {
        try {
            const execValue = preResolvedState ?? resolveDataProductExecutionState(dataProduct);
            this.dataProduct = dataProduct;
            this.setExecutionState(execValue);
            const mapping = this.executionState.mapping;
            if (mapping) {
                this.changeMapping(mapping);
            }
            if (this.executionState instanceof NativeModelDataProductExecutionState) {
                const runtime = guaranteeNonNullable(this.executionState.exectionValue.runtime, 'runtime unable to be resolved');
                this.changeRuntime(new RuntimePointer(runtime));
            }
            else if (this.executionState instanceof
                ModelAccessPointDataProductExecutionState &&
                this.executionState.selectedRuntime instanceof PackageableRuntime) {
                this.changeRuntime(this.executionState.selectedRuntime);
            }
            else if (this.executionState instanceof LakehouseDataProductExecutionState &&
                accessor &&
                this.executionState.selectedRuntime instanceof PackageableRuntime) {
                this.setSourceElement(accessor);
                this.changeRuntime(new RuntimePointer(PackageableElementExplicitReference.create(this.executionState.selectedRuntime)));
            }
            if (mapping) {
                const coverageResult = this.mappingToMappingCoverageResult?.get(mapping.path);
                if (coverageResult) {
                    this.explorerState.mappingModelCoverageAnalysisResult =
                        coverageResult;
                }
                const compatibleClasses = resolveUsableDataProductClasses(this.activeFeaturedElements, mapping, this.graphManagerState, coverageResult);
                // if there is no chosen class or the chosen one is not compatible
                // with the mapping then pick a compatible class if possible
                if (!this.sourceClass ||
                    !compatibleClasses.includes(this.sourceClass)) {
                    const possibleNewClass = compatibleClasses[0];
                    if (possibleNewClass) {
                        this.changeSourceElement(possibleNewClass);
                    }
                }
            }
        }
        catch (error) {
            assertErrorThrown(error);
            this.applicationStore.notificationService.notifyError(`Failed to load Data Product: ${error.message}`);
        }
    }
    copyDataProductLinkToClipBoard() {
        if (!this.isProductLinkable) {
            this.applicationStore.notificationService.notifyError('Data Product link is not available.');
        }
    }
    getElementType() {
        return DataProduct;
    }
    setExecutionState(val) {
        this.executionState =
            val instanceof NativeModelExecutionContext
                ? new NativeModelDataProductExecutionState(val, this)
                : val instanceof LakehouseAccessPoint
                    ? new LakehouseDataProductExecutionState(val, this)
                    : new ModelAccessPointDataProductExecutionState(val, this);
    }
    async changeExecutionState(val) {
        // preserve runtime selection when switching between Lakehouse access points
        // (or between Model access point groups) so users don't lose their chosen
        // runtime / adhoc runtime flag on every selector change.
        const previousState = this.executionState;
        let preservedRuntime;
        let preservedAdhocRuntime = false;
        if (previousState instanceof LakehouseDataProductExecutionState ||
            previousState instanceof ModelAccessPointDataProductExecutionState) {
            preservedRuntime = previousState.selectedRuntime;
            preservedAdhocRuntime = previousState.adhocRuntime;
        }
        this.setExecutionState(val);
        if (this.executionState instanceof LakehouseDataProductExecutionState ||
            this.executionState instanceof ModelAccessPointDataProductExecutionState) {
            if (preservedRuntime) {
                this.executionState.selectedRuntime = preservedRuntime;
            }
            this.executionState.adhocRuntime = preservedAdhocRuntime;
        }
        if (val instanceof LakehouseAccessPoint) {
            const relationMetadata = !this.dataProductArtifact
                ? await this.graphManagerState.graphManager.getLambdaRelationType(val.func, this.graphManagerState.graph)
                : undefined;
            const accessor = resolveDataProductAccessor(this.dataProduct, val, this.graphManagerState.graph, this.dataProductArtifact, relationMetadata);
            this.changeSourceElement(accessor);
        }
    }
    get modelAccessPointGroups() {
        return this.dataProduct.accessPointGroups.filter(filterByType(ModelAccessPointGroup));
    }
    get hasModelAccessPointGroups() {
        return this.modelAccessPointGroups.length > 0;
    }
    get modelAccessPointGroupOptions() {
        return this.modelAccessPointGroups
            .map(buildModelAccessPointGroupOption)
            .sort(compareLabelFn);
    }
    get activeMapping() {
        return this.executionState.mapping;
    }
    get activeFeaturedElements() {
        return this.executionState.featuredElements;
    }
    buildExecutionContextExpression(lambdaFunction) {
        if (this.executionState instanceof ModelAccessPointDataProductExecutionState) {
            // for model access point group with attached ->with(dataProduct)->from(runtime) to execute query
            let precedingExpression = guaranteeNonNullable(lambdaFunction.expressionSequence[0], `Can't build from() expression: preceding expression is not defined`);
            const withFunc = new SimpleFunctionExpression(extractElementNameFromPath(SUPPORTED_FUNCTIONS.WITH));
            const dataProductInstance = new InstanceValue(Multiplicity.ONE, undefined);
            dataProductInstance.values = [
                PackageableElementExplicitReference.create(this.dataProduct),
            ];
            withFunc.parametersValues = [precedingExpression, dataProductInstance];
            precedingExpression = withFunc;
            const fromFunc = new SimpleFunctionExpression(extractElementNameFromPath(SUPPORTED_FUNCTIONS.FROM));
            const runtime = this.executionState.selectedRuntime;
            if (runtime) {
                const runtimeInstance = new InstanceValue(Multiplicity.ONE, undefined);
                runtimeInstance.values = [
                    PackageableElementExplicitReference.create(runtime),
                ];
                fromFunc.parametersValues = [precedingExpression, runtimeInstance];
                lambdaFunction.expressionSequence[0] = fromFunc;
            }
            return lambdaFunction;
        }
        return super.buildExecutionContextExpression(lambdaFunction);
    }
    *loadEntities() {
        this.loadDataProductModelState.inProgress();
        this.entities = this.graphManagerState.graph.allOwnElements
            .filter(filterByType(this.getElementType()))
            .map((element) => this.transformElement(element));
        this.loadDataProductModelState.complete();
    }
    transformElement(element) {
        return new DepotEntityWithOrigin(undefined, element.name, element.path, CORE_PURE_PATH.DATA_PRODUCT);
    }
    get dataProductOptions() {
        const sortedAllOptions = (this.entities ?? [])
            .map(buildDataProductOption)
            .sort(compareLabelFn);
        return this.prioritizeEntityFunc
            ? [
                ...sortedAllOptions.filter((val) => this.prioritizeEntityFunc?.(val.value)),
                ...sortedAllOptions.filter((val) => !this.prioritizeEntityFunc?.(val.value)),
            ]
            : sortedAllOptions;
    }
    get selectedDataProductOption() {
        return {
            label: this.dataProduct.title ?? this.dataProduct.name,
            value: new DepotEntityWithOrigin(undefined, this.dataProduct.name, this.dataProduct.path, CORE_PURE_PATH.DATA_PRODUCT),
        };
    }
    get isSupported() {
        return (this.dataProduct.nativeModelAccess !== undefined ||
            // contains model access point group
            this.dataProduct.accessPointGroups.filter(filterByType(ModelAccessPointGroup)).length > 0 ||
            // contains lakehouse access point
            this.dataProduct.accessPointGroups.some((group) => group.accessPoints.some((ap) => ap instanceof LakehouseAccessPoint)));
    }
    // includes model access point group if more than one group
    get execOptions() {
        return (this.dataProduct.nativeModelAccess?.nativeModelExecutionContexts.map(buildExecOptions) ?? []).sort(compareLabelFn);
    }
    async propagateExecutionContextChange(requireReBuildingGraph) {
        const currentMapping = this.executionContextState.mapping;
        const newMapping = this.activeMapping;
        if (!newMapping || newMapping === currentMapping) {
            return;
        }
        const coverageResult = this.mappingToMappingCoverageResult?.get(newMapping.path);
        if (coverageResult && this.dataProductArtifact) {
            const origin = this.graphManagerState.graph.origin;
            if (origin instanceof LegendSDLC) {
                const newGraph = this.graphManagerState.createNewGraph();
                const projectInfo = {
                    groupId: origin.groupId,
                    artifactId: origin.artifactId,
                    versionId: origin.versionId,
                };
                let accessPointId;
                let dataProductAccessType;
                if (this.executionState instanceof NativeModelDataProductExecutionState) {
                    accessPointId = this.executionState.exectionValue.key;
                    dataProductAccessType = DataProductAccessType.NATIVE;
                }
                else if (this.executionState instanceof LakehouseDataProductExecutionState) {
                    accessPointId = this.executionState.exectionValue.id;
                    dataProductAccessType = DataProductAccessType.LAKEHOUSE;
                }
                else {
                    accessPointId = this.executionState.exectionValue.id;
                    dataProductAccessType = DataProductAccessType.MODEL;
                }
                const analysisResult = await this.graphManagerState.graphManager.buildDataProductAnalysis(this.dataProductArtifact, this.dataProduct.path, newGraph, accessPointId, dataProductAccessType, projectInfo);
                this.graphManagerState.graph = newGraph;
                this.dataProduct = newGraph.getDataProduct(this.dataProduct.path);
                this.setExecutionState(analysisResult.targetExecState);
                if (analysisResult.dataProductAnalysis.mappingToMappingCoverageResult) {
                    this.mappingToMappingCoverageResult =
                        analysisResult.dataProductAnalysis.mappingToMappingCoverageResult;
                }
                const newCoverageResult = this.mappingToMappingCoverageResult?.get(newMapping.path);
                if (newCoverageResult) {
                    this.explorerState.mappingModelCoverageAnalysisResult =
                        newCoverageResult;
                }
            }
            else {
                this.explorerState.mappingModelCoverageAnalysisResult = coverageResult;
            }
        }
        else if (coverageResult) {
            this.explorerState.mappingModelCoverageAnalysisResult = coverageResult;
        }
        await this.prepareAccessForExecution();
        this.changeMapping(newMapping, {
            keepQueryContent: true,
        });
        const classes = resolveUsableDataProductClasses(this.activeFeaturedElements, newMapping, this.graphManagerState, this.explorerState.mappingModelCoverageAnalysisResult);
        if (!this.sourceClass ||
            (!classes.includes(this.sourceClass) && classes.length)) {
            const possibleNewClass = classes[0];
            if (possibleNewClass) {
                this.changeSourceElement(possibleNewClass);
            }
        }
        this.explorerState.refreshTreeData();
    }
}
//# sourceMappingURL=DataProductQueryBuilderState.js.map