/**
 * 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 { observable, computed, action, makeObservable, flow } from 'mobx';
import { assertErrorThrown, guaranteeType, returnUndefOnError, } from '@finos/legend-shared';
import { UnsupportedServiceExecutionState, SingleServicePureExecutionState, MultiServicePureExecutionState, InlineServicePureExecutionState, } from './ServiceExecutionState.js';
import { ServiceRegistrationState } from '../../../editor-state/element-editor-state/service/ServiceRegistrationState.js';
import { ElementEditorState } from '../../../editor-state/element-editor-state/ElementEditorState.js';
import { Service, PureSingleExecution, PureMultiExecution, DeploymentOwnership, UserListOwnership, isStubbed_RawLambda, getValueSpecificationReturnType, resolveServiceQueryRawLambda, PureExecution, } from '@finos/legend-graph';
import { ServiceTestableState } from './testable/ServiceTestableState.js';
import { User } from '@finos/legend-server-sdlc';
import { ServicePostValidationsState } from './ServicePostValidationState.js';
import { valueSpecReturnTDS } from '@finos/legend-query-builder';
import { service_setOwnership } from '../../../../graph-modifier/DSL_Service_GraphModifierHelper.js';
export var SERVICE_TAB;
(function (SERVICE_TAB) {
    SERVICE_TAB["GENERAL"] = "GENERAL";
    SERVICE_TAB["EXECUTION"] = "EXECUTION";
    SERVICE_TAB["TEST"] = "TEST";
    SERVICE_TAB["REGISTRATION"] = "REGISTRATION";
    SERVICE_TAB["POST_VALIDATION"] = "POST_VALIDATION";
})(SERVICE_TAB || (SERVICE_TAB = {}));
var ServiceOwnershipType;
(function (ServiceOwnershipType) {
    ServiceOwnershipType["DEPLOYMENT_OWNERSHIP"] = "deploymentOwnership";
    ServiceOwnershipType["USERLIST_OWNERSHIP"] = "userListOwnership";
})(ServiceOwnershipType || (ServiceOwnershipType = {}));
export const resolveServiceQueryValueSpec = (service, editorStore) => {
    const rawLambda = resolveServiceQueryRawLambda(service);
    if (rawLambda) {
        return editorStore.graphManagerState.graphManager.buildValueSpecification(editorStore.graphManagerState.graphManager.serializeRawValueSpecification(rawLambda), editorStore.graphManagerState.graph);
    }
    return undefined;
};
export const resolveServiceQueryReturnType = (service, editorStore) => {
    const valueSpec = returnUndefOnError(() => resolveServiceQueryValueSpec(service, editorStore));
    if (valueSpec) {
        return returnUndefOnError(() => getValueSpecificationReturnType(valueSpec));
    }
    return undefined;
};
export const isServiceQueryTDS = (service, editorStore) => {
    const valueSpec = returnUndefOnError(() => resolveServiceQueryValueSpec(service, editorStore));
    return Boolean(valueSpec
        ? valueSpecReturnTDS(valueSpec, editorStore.graphManagerState.graph)
        : undefined);
};
export const MINIMUM_SERVICE_OWNERS = 2;
export const DeploymentOwnershipLabel = 'Deployment';
export const UserlistOwnershipLabel = 'User List';
export const OWNERSHIP_OPTIONS = [
    {
        label: DeploymentOwnershipLabel,
        value: ServiceOwnershipType.DEPLOYMENT_OWNERSHIP,
    },
    {
        label: UserlistOwnershipLabel,
        value: ServiceOwnershipType.USERLIST_OWNERSHIP,
    },
];
export class ServiceEditorState extends ElementEditorState {
    executionState;
    registrationState;
    testableState;
    selectedTab;
    postValidationState;
    constructor(editorStore, element) {
        super(editorStore, element);
        makeObservable(this, {
            executionState: observable,
            selectedOwnership: computed,
            registrationState: observable,
            selectedTab: observable,
            postValidationState: observable,
            setSelectedTab: action,
            setSelectedOwnership: action,
            resetExecutionState: action,
            openToTestTab: action,
            service: computed,
            reprocess: action,
            searchUsers: flow,
        });
        this.executionState = this.buildExecutionState();
        this.registrationState = new ServiceRegistrationState(editorStore, this.service, editorStore.applicationStore.config.options.TEMPORARY__serviceRegistrationConfig, editorStore.sdlcServerClient.featuresConfigHasBeenFetched &&
            editorStore.sdlcServerClient.features.canCreateVersion);
        this.testableState = new ServiceTestableState(editorStore, this);
        const executionQuery = this.service.execution instanceof PureExecution
            ? this.service.execution.func
            : undefined;
        // default to execution tab if query is defined
        this.selectedTab =
            executionQuery && !isStubbed_RawLambda(executionQuery)
                ? SERVICE_TAB.EXECUTION
                : SERVICE_TAB.GENERAL;
        this.postValidationState = new ServicePostValidationsState(this);
    }
    setSelectedTab(tab) {
        this.selectedTab = tab;
    }
    openToTestTab() {
        this.selectedTab = SERVICE_TAB.TEST;
    }
    get selectedOwnership() {
        const ownership = this.service.ownership;
        if (ownership instanceof DeploymentOwnership) {
            return {
                label: DeploymentOwnershipLabel,
                value: ServiceOwnershipType.DEPLOYMENT_OWNERSHIP,
            };
        }
        else if (ownership instanceof UserListOwnership) {
            return {
                label: UserlistOwnershipLabel,
                value: ServiceOwnershipType.USERLIST_OWNERSHIP,
            };
        }
        return undefined;
    }
    setSelectedOwnership(o) {
        switch (o.value) {
            case ServiceOwnershipType.DEPLOYMENT_OWNERSHIP: {
                service_setOwnership(this.service, new DeploymentOwnership('', this.service));
                break;
            }
            case ServiceOwnershipType.USERLIST_OWNERSHIP: {
                const currentUserId = this.editorStore.graphManagerState.graphManager.TEMPORARY__getEngineConfig()
                    .currentUserId;
                service_setOwnership(this.service, new UserListOwnership(currentUserId ? [currentUserId] : [], this.service));
                break;
            }
            default: {
                this.editorStore.applicationStore.notificationService.notifyError('Unsupported ownership type');
            }
        }
    }
    resetExecutionState() {
        this.executionState = this.buildExecutionState();
    }
    buildExecutionState() {
        const execution = this.service.execution;
        if (execution instanceof PureSingleExecution &&
            execution.mapping &&
            execution.runtime) {
            return new SingleServicePureExecutionState(this.editorStore, this, execution);
        }
        else if (execution instanceof PureSingleExecution) {
            return new InlineServicePureExecutionState(this.editorStore, this, execution);
        }
        else if (execution instanceof PureMultiExecution &&
            execution.executionParameters) {
            return new MultiServicePureExecutionState(this.editorStore, this, execution);
        }
        return new UnsupportedServiceExecutionState(this.editorStore, this, this.service.execution);
    }
    get service() {
        return guaranteeType(this.element, Service, 'Element inside service editor state must be a service');
    }
    *searchUsers(name) {
        try {
            return (yield this.editorStore.sdlcServerClient.getUsers(name)).map((p) => User.serialization.fromJson(p));
        }
        catch (error) {
            assertErrorThrown(error);
            this.editorStore.applicationStore.notificationService.notifyError(error);
            return [];
        }
    }
    reprocess(newElement, editorStore) {
        const serviceEditorState = new ServiceEditorState(editorStore, newElement);
        serviceEditorState.selectedTab = this.selectedTab;
        return serviceEditorState;
    }
}
//# sourceMappingURL=ServiceEditorState.js.map