/**
 * 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 { IngestDefinition, Database, PackageableElementExplicitReference, RuntimePointer, buildRawLambdaFromLambdaFunction, } from '@finos/legend-graph';
import { QueryBuilderState } from '../../QueryBuilderState.js';
import { renderAccessorQueryBuilderSetupPanelContent } from '../../../components/workflows/AccessorQueryBuilder.js';
import { action, computed, makeObservable, runInAction } from 'mobx';
import { buildElementOption } from '@finos/legend-lego/graph-editor';
import { getCompatibleRuntimesFromAccessorOwner } from './AccessorQueryBuilderHelper.js';
import { QueryBuilderEmbeddedFromExecutionContextState } from '../../QueryBuilderExecutionContextState.js';
import { QueryBuilderTDSState } from '../../fetch-structure/tds/QueryBuilderTDSState.js';
import { buildLambdaFunction } from '../../QueryBuilderValueSpecificationBuilder.js';
export class AccessorQueryBuilderState extends QueryBuilderState {
    TEMPORARY__setupPanelContentRenderer = () => renderAccessorQueryBuilderSetupPanelContent(this);
    constructor(applicationStore, accessor, graphManagerState, workflow, actionConfig, config, sourceInfo) {
        super(applicationStore, graphManagerState, workflow, config, sourceInfo);
        makeObservable(this, {
            changeAccessorOwner: action,
            changeAccessor: action,
            accessorOwnerOptions: computed,
            accessorLabel: computed,
            compatibleRuntimes: computed,
        });
        this.workflowState.updateActionConfig(actionConfig);
        if (accessor) {
            this.changeSourceElement(accessor);
        }
        this.configureFilterPanelsForAccessor();
        // force from.
        this.executionContextState =
            new QueryBuilderEmbeddedFromExecutionContextState(this);
    }
    // we will not include data product as it is own state
    get accessorOwners() {
        return [
            ...this.graphManagerState.graph.ingests,
            ...this.graphManagerState.usableDatabases,
        ];
    }
    get accessorLabel() {
        return this.sourceAccessor?.accessorLabel ?? 'Accessor';
    }
    get accessorOwnerOptions() {
        return this.accessorOwners.map(buildElementOption);
    }
    get selectedAccessorOwner() {
        return this.sourceAccessor?.parentElement;
    }
    get accessors() {
        if (this.selectedAccessorOwner instanceof IngestDefinition) {
            const content = this.selectedAccessorOwner
                .content;
            return (content.datasets?.map((e) => ({
                tableName: e.name,
            })) ?? []);
        }
        else if (this.selectedAccessorOwner instanceof Database) {
            return this.selectedAccessorOwner.schemas.flatMap((schema) => schema.tables.map((table) => ({
                schemaName: schema.name,
                tableName: table.name,
            })));
        }
        return [];
    }
    get accessorsOptions() {
        return this.accessors.map((accessor) => ({
            label: accessor.schemaName
                ? `${accessor.schemaName}.${accessor.tableName}`
                : accessor.tableName,
            value: accessor,
        }));
    }
    get compatibleRuntimes() {
        const owner = this.selectedAccessorOwner;
        if (!owner) {
            return [];
        }
        return getCompatibleRuntimesFromAccessorOwner(owner, this.graphManagerState);
    }
    get requiresMappingForExecution() {
        return false;
    }
    /**
     * In accessor mode, configure both filter and post-filter panels to be visible.
     */
    configureFilterPanelsForAccessor() {
        const tdsState = this.fetchStructureState.implementation;
        if (tdsState instanceof QueryBuilderTDSState) {
            tdsState.setShowPostFilterPanel(true);
        }
    }
    async changeAccessorOwner(accessorOwner) {
        const accessor = await this.graphManagerState.graphManager.createAccessorFromPackageableElement(accessorOwner, this.graphManagerState.graph);
        if (accessor) {
            runInAction(() => {
                this.changeSourceElement(accessor);
                this.configureFilterPanelsForAccessor();
            });
        }
    }
    async changeAccessor(value) {
        const owner = this.selectedAccessorOwner;
        if (owner) {
            const accessor = await this.graphManagerState.graphManager.createAccessorFromPackageableElement(owner, this.graphManagerState.graph, {
                schemaName: value.schemaName,
                tableName: value.tableName,
            });
            if (accessor) {
                runInAction(() => {
                    this.changeSourceElement(accessor);
                    this.configureFilterPanelsForAccessor();
                });
            }
        }
    }
    changeSelectedRuntime(val) {
        this.changeRuntime(new RuntimePointer(PackageableElementExplicitReference.create(val)));
    }
    buildQueryForPersistence() {
        if (!this.isQuerySupported) {
            return this.buildQuery();
        }
        return buildRawLambdaFromLambdaFunction(buildLambdaFunction(this, {
            skipExecutionContext: true,
            useTypedRelationFunctions: this.isFetchStructureTyped,
        }), this.graphManagerState);
    }
}
//# sourceMappingURL=AccessorQueryBuilderState.js.map