/**
 * 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 { GRAPH_MANAGER_EVENT, IngestDefinition, } from '@finos/legend-graph';
import { ElementEditorState } from '../ElementEditorState.js';
import { ActionState, assertErrorThrown, assertTrue, guaranteeNonNullable, guaranteeType, LogEvent, removePrefix, } from '@finos/legend-shared';
import { action, computed, flow, flowResult, makeObservable, observable, } from 'mobx';
import { EditorInitialConfiguration, IngestElementEditorInitialConfiguration, } from '../ElementEditorInitialConfiguration.js';
import { EXTERNAL_APPLICATION_NAVIGATION__generateUrlWithEditorConfig } from '../../../../../__lib__/LegendStudioNavigation.js';
import { LineageState } from '@finos/legend-query-builder';
import { LegendStudioTelemetryHelper } from '../../../../../__lib__/LegendStudioTelemetryHelper.js';
const createEditorInitialConfiguration = () => {
    const config = new EditorInitialConfiguration();
    const ingest = new IngestElementEditorInitialConfiguration();
    ingest.deployOnOpen = true;
    config.elementEditorConfiguration = ingest;
    return config;
};
const editorInitialConfigToBase64 = (val) => btoa(JSON.stringify(EditorInitialConfiguration.serialization.toJson(val)));
export const generateUrlToDeployOnOpen = (val) => {
    return val.editorStore.applicationStore.navigationService.navigator.generateAddress(EXTERNAL_APPLICATION_NAVIGATION__generateUrlWithEditorConfig(val.editorStore.editorMode.generateElementLink(val.ingest.path), editorInitialConfigToBase64(createEditorInitialConfiguration())));
};
const PARSER_SECTION = `###Lakehouse`;
export class IngestDefinitionEditorState extends ElementEditorState {
    validateAndDeployResponse;
    deploymentState = ActionState.create();
    lineageGenerationState = ActionState.create();
    deployOnOpen = false;
    lineageState;
    constructor(editorStore, element, config) {
        super(editorStore, element);
        makeObservable(this, {
            deploymentState: observable,
            deployOnOpen: observable,
            setDeployOnOpen: observable,
            validateAndDeployResponse: observable,
            deploymentResponse: computed,
            setValidateAndDeployResponse: action,
            init_with_deploy: flow,
            deploy: flow,
            generateLineage: flow,
        });
        if (config?.elementEditorConfiguration instanceof
            IngestElementEditorInitialConfiguration) {
            this.deployOnOpen =
                config.elementEditorConfiguration.deployOnOpen ?? false;
        }
        this.lineageState = new LineageState(this.editorStore.applicationStore);
    }
    get deploymentResponse() {
        return (this.validateAndDeployResponse?.deploymentResponse ??
            this.validateAndDeployResponse?.validationResponse);
    }
    get ingestionManager() {
        return this.editorStore.ingestionManager;
    }
    setValidateAndDeployResponse(val) {
        this.validateAndDeployResponse = val;
    }
    setDeployOnOpen(value) {
        this.deployOnOpen = value;
    }
    *init_with_deploy(auth) {
        this.setDeployOnOpen(false);
        if (!auth.isAuthenticated) {
            auth
                .signinRedirect({
                state: generateUrlToDeployOnOpen(this),
            })
                .catch(this.editorStore.applicationStore.alertUnhandledError);
            return;
        }
        const token = auth.user?.access_token;
        yield flowResult(this.generateElementGrammar()).catch(this.editorStore.applicationStore.alertUnhandledError);
        flowResult(this.deploy(token)).catch(this.editorStore.applicationStore.alertUnhandledError);
    }
    *deploy(token) {
        try {
            assertTrue(this.validForDeployment, 'Ingest definition is not valid for deployment');
            this.deploymentState.inProgress();
            const response = (yield guaranteeNonNullable(this.ingestionManager).deploy(
            // remove parser prefix for now since api already expects it to be under lakehouse parser
            guaranteeNonNullable(removePrefix(this.textContent, PARSER_SECTION)), guaranteeNonNullable(this.ingest.appDirDeployment), (val) => this.editorStore.applicationStore.alertService.setBlockingAlert({
                message: val,
                showLoading: true,
            }), token));
            this.editorStore.applicationStore.alertService.setBlockingAlert(undefined);
            if (response.deploymentResponse) {
                LegendStudioTelemetryHelper.logEvent_LakehouseDeployIngest(this.editorStore.applicationStore.telemetryService, this.editorStore.editorMode.getSourceInfo(), response.deploymentResponse.ingestDefinitionUrn, this.ingest.path);
            }
            this.setValidateAndDeployResponse(response);
        }
        catch (error) {
            this.editorStore.applicationStore.alertService.setBlockingAlert(undefined);
            assertErrorThrown(error);
            LegendStudioTelemetryHelper.logEvent_LakehouseDeployIngestFailure(this.editorStore.applicationStore.telemetryService, this.editorStore.editorMode.getSourceInfo(), this.ingest.path, error.message);
            this.editorStore.applicationStore.notificationService.notifyError(`Ingest definition failed to deploy: ${error.message}`);
        }
        finally {
            this.deploymentState.complete();
        }
    }
    getMatviewFuncNames() {
        return (this.ingest.TEMPORARY_MATVIEW_FUNCTION_DATA_SETS?.map((dataset) => dataset.name) ?? []);
    }
    *generateLineage(matviewDataset) {
        if (this.lineageGenerationState.isInProgress) {
            this.editorStore.applicationStore.notificationService.notifyError('Lineage generation in progress already');
            return;
        }
        try {
            this.lineageGenerationState.inProgress();
            const query = matviewDataset.source.function;
            const lineageRawData = (yield this.editorStore.graphManagerState.graphManager.generateLineage(query, undefined, undefined, this.editorStore.graphManagerState.graph, undefined));
            const lineageData = this.editorStore.graphManagerState.graphManager.buildLineage(lineageRawData);
            this.lineageState.setLineageData(lineageData);
        }
        catch (error) {
            assertErrorThrown(error);
            this.editorStore.applicationStore.logService.error(LogEvent.create(GRAPH_MANAGER_EVENT.LINEAGE_GENERATION_FAILURE), error);
            this.editorStore.applicationStore.notificationService.notifyError(error);
        }
        finally {
            this.lineageGenerationState.complete();
        }
    }
    reprocess(newElement, editorStore) {
        return new IngestDefinitionEditorState(editorStore, newElement);
    }
    get validForDeployment() {
        return Boolean(this.ingest.appDirDeployment && this.textContent && this.ingestionManager);
    }
    get validForLineageViewer() {
        return Boolean(this.ingest.TEMPORARY_MATVIEW_FUNCTION_DATA_SETS?.length);
    }
    get validationMessage() {
        if (!this.ingest.appDirDeployment) {
            return 'No app dir deployment found';
        }
        else if (!this.textContent) {
            return 'No ingest definition found';
        }
        else if (!this.ingestionManager) {
            return 'No ingestion manager found';
        }
        return 'Deploy';
    }
    get ingest() {
        return guaranteeType(this.element, IngestDefinition, 'Element inside ingest editor state must be a IngestDefinition');
    }
}
//# sourceMappingURL=IngestDefinitionEditorState.js.map