/**
 * 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 { assertErrorThrown, UnsupportedOperationError, } from '@finos/legend-shared';
import { V1_PackageableElementPointer, } from '../../../model/packageableElements/V1_PackageableElement.js';
import { V1_transformAssociation, V1_transformClass, V1_transformEnumeration, V1_transformFunction, V1_transformMeasure, V1_transformProfile, V1_transformStereotype, V1_transformTaggedValue, } from './V1_DomainTransformer.js';
import { V1_transformSectionIndex } from './V1_SectionIndexTransformer.js';
import { V1_transformFileGeneration, V1_transformGenerationSpecification, } from './V1_GenerationSpecificationTransformer.js';
import { V1_transformFlatData } from './V1_FlatDataTransformer.js';
import { V1_transformDatabase } from './V1_DatabaseTransformer.js';
import { V1_transformMapping } from './V1_MappingTransformer.js';
import { V1_transformService } from './V1_ServiceTransformer.js';
import { V1_transformPackageableRuntime } from './V1_RuntimeTransformer.js';
import { V1_transformPackageableConnection } from './V1_ConnectionTransformer.js';
import { V1_transformDataElement } from './V1_DataElementTransformer.js';
import { V1_transformExecutionEnvirnoment } from './V1_ExecutionEnvironmentTransformer.js';
import { V1_INTERNAL__UnknownPackageableElement } from '../../../model/packageableElements/V1_INTERNAL__UnknownPackageableElement.js';
import { V1_initPackageableElement } from './V1_CoreTransformerHelper.js';
import { V1_INTERNAL__UnknownFunctionActivator } from '../../../model/packageableElements/function/V1_INTERNAL__UnknownFunctionActivator.js';
import { V1_INTERNAL__UnknownStore } from '../../../model/packageableElements/store/V1_INTERNAL__UnknownStore.js';
import { generateFunctionPrettyName } from '../../../../../../../graph/helpers/PureLanguageHelper.js';
import { V1_SnowflakeApp } from '../../../model/packageableElements/function/V1_SnowflakeApp.js';
import { V1_SnowflakeM2MUdf } from '../../../model/packageableElements/function/V1_SnowflakeM2MUdf.js';
import { V1_transformDeployment, V1_transformHostedServiceDeploymentConfiguration, V1_transformOwnership, V1_transformSnowflakeAppDeploymentConfiguration, V1_transformSnowflakeM2MUdfDeploymentConfiguration, V1_transformActions, V1_transformMemSQLDeploymentConfiguration, } from './V1_FunctionActivatorTransformer.js';
import { PackageableElementPointerType } from '../../../../../../../graph/MetaModelConst.js';
import { V1_INTERNAL__UnknownElement } from '../../../model/packageableElements/V1_INTERNAL__UnknownElement.js';
import { V1_HostedService } from '../../../model/packageableElements/function/V1_HostedService.js';
import { V1_transformFunctionActivatorActions } from '../to/helpers/V1_LegendLambdaTransformerHelper.js';
import { V1_transformDataProduct } from './V1_DataProductTransformer.js';
import { V1_IngestDefinition } from '../../../model/packageableElements/ingest/V1_IngestDefinition.js';
import { V1_MemSQLFunction } from '../../../model/packageableElements/function/V1_MemSQLFunction.js';
class V1_PackageableElementTransformer {
    context;
    extraElementTransformers = [];
    constructor(plugins, context) {
        this.extraElementTransformers = plugins.flatMap((plugin) => plugin.V1_getExtraElementTransformers?.() ?? []);
        this.context = context;
    }
    visit_PackageableElement(element) {
        for (const transformer of this.extraElementTransformers) {
            const elementProtocol = transformer(element, this.context);
            if (elementProtocol) {
                return elementProtocol;
            }
        }
        throw new UnsupportedOperationError(`Can't transform element '${element.path}': no compatible transformer available from plugins`, element);
    }
    visit_INTERNAL__UnknownElement(element) {
        const protocol = new V1_INTERNAL__UnknownElement();
        V1_initPackageableElement(protocol, element);
        protocol.content = element.content;
        protocol.classifierPath = element.classifierPath;
        return protocol;
    }
    visit_INTERNAL__UnknownPackageableElement(element) {
        const protocol = new V1_INTERNAL__UnknownPackageableElement();
        V1_initPackageableElement(protocol, element);
        protocol.content = element.content;
        return protocol;
    }
    visit_IngestDefinition(element) {
        const protocol = new V1_IngestDefinition();
        V1_initPackageableElement(protocol, element);
        protocol.content = element.content;
        // we don't take into account appDirDeployment here as it is still read only
        return protocol;
    }
    visit_INTERNAL__UnknownFunctionActivator(element) {
        const protocol = new V1_INTERNAL__UnknownFunctionActivator();
        V1_initPackageableElement(protocol, element);
        protocol.function = new V1_PackageableElementPointer(PackageableElementPointerType.FUNCTION, generateFunctionPrettyName(element.function.value, {
            fullPath: true,
            spacing: false,
        }));
        protocol.content = element.content;
        return protocol;
    }
    visit_SnowflakeApp(element) {
        const protocol = new V1_SnowflakeApp();
        V1_initPackageableElement(protocol, element);
        protocol.function = new V1_PackageableElementPointer(PackageableElementPointerType.FUNCTION, generateFunctionPrettyName(element.function.value, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }));
        protocol.applicationName = element.applicationName;
        if (element.usageRole) {
            protocol.usageRole = element.usageRole;
        }
        if (element.deploymentSchema) {
            protocol.deploymentSchema = element.deploymentSchema;
        }
        if (element.permissionScheme) {
            protocol.permissionScheme = element.permissionScheme;
        }
        protocol.description = element.description;
        protocol.ownership = V1_transformDeployment(element.ownership);
        protocol.activationConfiguration =
            V1_transformSnowflakeAppDeploymentConfiguration(element.activationConfiguration);
        protocol.stereotypes = element.stereotypes.map(V1_transformStereotype);
        protocol.taggedValues = element.taggedValues.map(V1_transformTaggedValue);
        V1_transformFunctionActivatorActions(protocol, element, this.context);
        return protocol;
    }
    visit_SnowflakeM2MUdf(element) {
        const protocol = new V1_SnowflakeM2MUdf();
        V1_initPackageableElement(protocol, element);
        protocol.function = new V1_PackageableElementPointer(PackageableElementPointerType.FUNCTION, generateFunctionPrettyName(element.function.value, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }));
        protocol.udfName = element.udfName;
        protocol.deploymentSchema = element.deploymentSchema;
        protocol.deploymentStage = element.deploymentStage;
        protocol.description = element.description;
        protocol.ownership = V1_transformDeployment(element.ownership);
        protocol.activationConfiguration =
            V1_transformSnowflakeM2MUdfDeploymentConfiguration(element.activationConfiguration);
        protocol.stereotypes = element.stereotypes.map(V1_transformStereotype);
        protocol.taggedValues = element.taggedValues.map(V1_transformTaggedValue);
        V1_transformFunctionActivatorActions(protocol, element, this.context);
        return protocol;
    }
    visit_HostedService(element) {
        const protocol = new V1_HostedService();
        V1_initPackageableElement(protocol, element);
        protocol.function = new V1_PackageableElementPointer(PackageableElementPointerType.FUNCTION, generateFunctionPrettyName(element.function.value, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }));
        protocol.documentation = element.documentation;
        protocol.pattern = element.pattern;
        protocol.autoActivateUpdates = element.autoActivateUpdates;
        protocol.storeModel = element.storeModel;
        protocol.generateLineage = element.generateLineage;
        protocol.ownership = V1_transformOwnership(element.ownership);
        protocol.actions = V1_transformActions(element.actions, this.context);
        if (element.activationConfiguration) {
            protocol.activationConfiguration =
                V1_transformHostedServiceDeploymentConfiguration(element.activationConfiguration);
        }
        protocol.taggedValues = element.taggedValues.map(V1_transformTaggedValue);
        protocol.stereotypes = element.stereotypes.map(V1_transformStereotype);
        return protocol;
    }
    visit_MemSQLFunction(element) {
        const protocol = new V1_MemSQLFunction();
        V1_initPackageableElement(protocol, element);
        protocol.function = new V1_PackageableElementPointer(PackageableElementPointerType.FUNCTION, generateFunctionPrettyName(element.function.value, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }));
        protocol.functionName = element.functionName;
        protocol.description = element.description;
        protocol.ownership = V1_transformDeployment(element.ownership);
        protocol.activationConfiguration =
            V1_transformMemSQLDeploymentConfiguration(element.activationConfiguration);
        protocol.stereotypes = element.stereotypes.map(V1_transformStereotype);
        protocol.taggedValues = element.taggedValues.map(V1_transformTaggedValue);
        V1_transformFunctionActivatorActions(protocol, element, this.context);
        return protocol;
    }
    visit_INTERNAL__UnknownStore(element) {
        const protocol = new V1_INTERNAL__UnknownStore();
        V1_initPackageableElement(protocol, element);
        protocol.content = element.content;
        return protocol;
    }
    visit_Package(element) {
        throw new UnsupportedOperationError();
    }
    visit_SectionIndex(element) {
        return V1_transformSectionIndex(element);
    }
    visit_PrimitiveType(element) {
        throw new UnsupportedOperationError();
    }
    visit_Profile(element) {
        return V1_transformProfile(element);
    }
    visit_Enumeration(element) {
        return V1_transformEnumeration(element);
    }
    visit_Measure(element) {
        return V1_transformMeasure(element, this.context);
    }
    visit_Class(element) {
        return V1_transformClass(element, this.context);
    }
    visit_Association(element) {
        return V1_transformAssociation(element, this.context);
    }
    visit_ConcreteFunctionDefinition(element) {
        return V1_transformFunction(element, this.context);
    }
    visit_FlatData(element) {
        return V1_transformFlatData(element);
    }
    visit_Database(element) {
        return V1_transformDatabase(element, this.context);
    }
    visit_DataProduct(element) {
        return V1_transformDataProduct(element, this.context);
    }
    visit_Mapping(element) {
        return V1_transformMapping(element, this.context);
    }
    visit_Service(element) {
        return V1_transformService(element, this.context);
    }
    visit_PackageableRuntime(element) {
        return V1_transformPackageableRuntime(element, this.context);
    }
    visit_PackageableConnection(element) {
        return V1_transformPackageableConnection(element, this.context);
    }
    visit_FileGenerationSpecification(element) {
        return V1_transformFileGeneration(element);
    }
    visit_GenerationSpecification(element) {
        return V1_transformGenerationSpecification(element);
    }
    visit_DataElement(element) {
        return V1_transformDataElement(element, this.context);
    }
    visit_ExecutionEnvironmentInstance(element) {
        return V1_transformExecutionEnvirnoment(element, this.context);
    }
}
export const V1_transformPackageableElement = (element, plugins, context) => {
    try {
        return element.accept_PackageableElementVisitor(new V1_PackageableElementTransformer(plugins, context));
    }
    catch (error) {
        assertErrorThrown(error);
        // TODO?: should we wrap this in GraphTransformerError?
        error.message = `Can't transform element '${element.path}': ${error.message}`;
        throw error;
    }
};
//# sourceMappingURL=V1_PackageableElementTransformer.js.map