/**
 * 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 { ActionAlertActionType, ActionAlertType, } from '@finos/legend-application';
import { ActionState, assertErrorThrown, assertNonNullable, } from '@finos/legend-shared';
import { action, computed, flow, makeObservable, observable } from 'mobx';
export var QueryBuilderDiffViewMode;
(function (QueryBuilderDiffViewMode) {
    QueryBuilderDiffViewMode["JSON"] = "JSON";
    QueryBuilderDiffViewMode["GRAMMAR"] = "Grammar";
})(QueryBuilderDiffViewMode || (QueryBuilderDiffViewMode = {}));
export class QueryBuilderDiffViewState {
    changeDetectionState;
    initialQuery;
    currentQuery;
    mode = QueryBuilderDiffViewMode.GRAMMAR;
    initialQueryGrammarText;
    currentQueryGrammarText;
    constructor(changeDetectionState, initialQuery, currentQuery) {
        makeObservable(this, {
            mode: observable,
            initialQueryGrammarText: observable,
            currentQueryGrammarText: observable,
            setMode: action,
            generateGrammarDiff: flow,
        });
        this.changeDetectionState = changeDetectionState;
        this.initialQuery = initialQuery;
        this.currentQuery = currentQuery;
    }
    setMode(val) {
        this.mode = val;
    }
    *generateGrammarDiff() {
        try {
            this.initialQueryGrammarText =
                (yield this.changeDetectionState.querybuilderState.graphManagerState.graphManager.lambdaToPureCode(this.initialQuery, true));
        }
        catch (error) {
            assertErrorThrown(error);
            this.initialQueryGrammarText =
                '/* Failed to transform grammar text, see JSON diff instead */';
        }
        try {
            this.currentQueryGrammarText =
                (yield this.changeDetectionState.querybuilderState.graphManagerState.graphManager.lambdaToPureCode(this.currentQuery, true));
        }
        catch (error) {
            assertErrorThrown(error);
            this.currentQueryGrammarText =
                '/* Failed to transform grammar text, see JSON diff instead */';
        }
    }
}
export class QueryBuilderChangeDetectionState {
    querybuilderState;
    initState = ActionState.create();
    querySnapshot;
    hashCodeSnapshot;
    diffViewState;
    constructor(queryBuilderState) {
        makeObservable(this, {
            diffViewState: observable,
            querySnapshot: observable,
            hashCodeSnapshot: observable,
            hasChanged: computed,
            initialize: action,
            showDiffViewPanel: action,
            hideDiffViewPanel: action,
        });
        this.querybuilderState = queryBuilderState;
    }
    showDiffViewPanel() {
        this.diffViewState = this.buildQueryBuilderDiffViewState();
    }
    buildQueryBuilderDiffViewState() {
        assertNonNullable(this.querySnapshot, `Can't show changes: change detection is not properly initialized`);
        return new QueryBuilderDiffViewState(this, this.querySnapshot, this.querybuilderState.buildQuery());
    }
    hideDiffViewPanel() {
        this.diffViewState = undefined;
    }
    get hasChanged() {
        if (!this.initState.hasCompleted) {
            return false;
        }
        return this.querybuilderState.hashCode !== this.hashCodeSnapshot;
    }
    initialize(initialQuery) {
        this.initState.inProgress();
        this.hashCodeSnapshot = this.querybuilderState.hashCode;
        this.querySnapshot = initialQuery;
        this.initState.complete();
    }
    alertUnsavedChanges(onProceed) {
        if (this.hasChanged) {
            this.querybuilderState.applicationStore.alertService.setActionAlertInfo({
                message: 'Unsaved changes will be lost if you continue. Do you still want to proceed?',
                type: ActionAlertType.CAUTION,
                actions: [
                    {
                        label: 'Proceed',
                        type: ActionAlertActionType.PROCEED_WITH_CAUTION,
                        handler: this.querybuilderState.applicationStore.guardUnhandledError(async () => onProceed()),
                    },
                    {
                        label: 'Abort',
                        type: ActionAlertActionType.PROCEED,
                        default: true,
                    },
                ],
            });
        }
        else {
            onProceed();
        }
    }
}
//# sourceMappingURL=QueryBuilderChangeDetectionState.js.map