/**
 * 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 { isNonNullable, assertNonEmptyString, UnsupportedOperationError, IllegalStateError, assertNonNullable, assertTrue, LogEvent, guaranteeType, guaranteeNonNullable, returnUndefOnError, } from '@finos/legend-shared';
import { Stereotype } from '../../../../../../../graph/metamodel/pure/packageableElements/domain/Stereotype.js';
import { Tag } from '../../../../../../../graph/metamodel/pure/packageableElements/domain/Tag.js';
import { Enum } from '../../../../../../../graph/metamodel/pure/packageableElements/domain/Enum.js';
import { V1_buildFullPath, } from './V1_GraphBuilderContext.js';
import { V1_buildVariable, V1_buildUnit, V1_buildTaggedValue, V1_buildFunctionSuite, } from './helpers/V1_DomainBuilderHelper.js';
import { V1_buildServiceExecution, V1_buildLegacyServiceTest, V1_buildPostValidation, V1_buildServiceOwnership, } from './helpers/V1_ServiceBuilderHelper.js';
import { V1_buildEnumerationMapping, V1_buildMappingInclude, } from './helpers/V1_MappingBuilderHelper.js';
import { V1_buildFlatDataSection } from './helpers/V1_FlatDataStoreBuilderHelper.js';
import { V1_buildSchema, V1_initInternalLakehouseGeneratedDatabase, } from './helpers/V1_DatabaseBuilderHelper.js';
import { V1_buildConfigurationProperty, V1_buildScopeElement, } from './helpers/V1_FileGenerationBuilderHelper.js';
import { V1_buildEngineRuntime } from './helpers/V1_RuntimeBuilderHelper.js';
import { V1_buildConnection } from './helpers/V1_ConnectionBuilderHelper.js';
import { V1_ConnectionPointer } from '../../../model/packageableElements/connection/V1_ConnectionPointer.js';
import { V1_buildGenerationTreeNode, V1_buildFileGenerationPointer, } from './helpers/V1_GenerationSpecificationBuilderHelper.js';
import { V1_buildSection } from './helpers/V1_SectionBuilderHelper.js';
import { V1_buildEmbeddedData } from './helpers/V1_DataElementBuilderHelper.js';
import { V1_buildTestSuite } from './helpers/V1_TestBuilderHelper.js';
import { ServiceTestSuite } from '../../../../../../../graph/metamodel/pure/packageableElements/service/ServiceTestSuite.js';
import { V1_DataElementReference } from '../../../model/data/V1_EmbeddedData.js';
import { V1_buildFunctionSignature } from '../../../helpers/V1_DomainHelper.js';
import { getFunctionName } from '../../../../../../../graph/helpers/DomainHelper.js';
import { GraphBuilderError } from '../../../../../../GraphManagerUtils.js';
import { PostValidation } from '../../../../../../../graph/metamodel/pure/packageableElements/service/PostValidation.js';
import { V1_buildExecutionParameters } from './V1_ExecutionEnvironmentBuilderHelper.js';
import { PackageableElementExplicitReference, PackageableElementImplicitReference, } from '../../../../../../../graph/metamodel/pure/packageableElements/PackageableElementReference.js';
import { generateFunctionPrettyName } from '../../../../../../../graph/helpers/PureLanguageHelper.js';
import { V1_MappingIncludeMapping, } from '../../../model/packageableElements/mapping/V1_MappingInclude.js';
import { V1_MappingIncludeDataProduct } from '../../../model/packageableElements/dataProduct/V1_MappingIncludeDataProduct.js';
import { V1_INTERNAL__UnknownMappingInclude } from '../../../model/packageableElements/mapping/V1_INTERNAL__UnknownMappingInclude.js';
import { V1_buildHostedServiceDeploymentConfiguration, V1_buildSnowflakeAppDeploymentConfiguration, V1_buildSnowflakeM2MUdfDeploymentConfiguration, V1_buildDeploymentOwnership, V1_builHostedServiceOwnership, V1_buildHostedServiceActions, V1_buildMemSQLDeploymentConfiguration, } from './helpers/V1_FunctionActivatorBuilderHelper.js';
import { V1_ExternalDataProductType, V1_InternalDataProductType, } from '../../../model/packageableElements/dataProduct/V1_DataProduct.js';
import { Email, ExternalDataProductType, InternalDataProductType, ModelAccessPointGroup, SupportInfo, } from '../../../../../../../graph/metamodel/pure/dataProduct/DataProduct.js';
import { V1_buildAccessPointGroup, V1_buildDataProductExpertise, V1_buildDataProductIcon, V1_buildDataProductLink, V1_buildDataProductOperationalMetadata, V1_buildNativeModelAccess, } from './helpers/V1_DataProductBuilder.js';
import { IncludeStore } from '../../../../../../../graph/metamodel/pure/packageableElements/store/relational/model/IncludeStore.js';
export class V1_ElementSecondPassBuilder {
    context;
    constructor(context) {
        this.context = context;
    }
    visit_PackageableElement(element) {
        this.context.extensions
            .getExtraBuilderOrThrow(element)
            .runSecondPass(element, this.context);
    }
    visit_INTERNAL__UnknownElement(element) {
        throw new UnsupportedOperationError();
    }
    visit_INTERNAL__UnknownPackageableElement(element) {
        throw new UnsupportedOperationError();
    }
    visit_IngestDefinition(element) {
        throw new UnsupportedOperationError();
    }
    visit_INTERNAL__UnknownFunctionActivator(element) {
        const metamodel = this.context.currentSubGraph.getOwnFunctionActivator(V1_buildFullPath(element.package, element.name));
        metamodel.function = PackageableElementExplicitReference.create(guaranteeNonNullable(this.context.graph.functions.find((fn) => generateFunctionPrettyName(fn, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }) === element.function.path.replaceAll(/\s*/gu, ''))));
    }
    visit_SnowflakeApp(element) {
        const metamodel = this.context.currentSubGraph.getOwnFunctionActivator(V1_buildFullPath(element.package, element.name));
        metamodel.function = PackageableElementExplicitReference.create(guaranteeNonNullable(this.context.graph.functions.find((fn) => generateFunctionPrettyName(fn, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }) === element.function.path.replaceAll(/\s*/gu, ''))));
        metamodel.ownership = V1_buildDeploymentOwnership(element.ownership, metamodel);
        metamodel.activationConfiguration =
            V1_buildSnowflakeAppDeploymentConfiguration(element.activationConfiguration, this.context);
        metamodel.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        metamodel.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
    }
    visit_MemSQLFunction(element) {
        const metamodel = this.context.currentSubGraph.getOwnFunctionActivator(V1_buildFullPath(element.package, element.name));
        metamodel.function = PackageableElementExplicitReference.create(guaranteeNonNullable(this.context.graph.functions.find((fn) => generateFunctionPrettyName(fn, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }) === element.function.path.replaceAll(/\s*/gu, ''))));
        metamodel.ownership = V1_buildDeploymentOwnership(element.ownership, metamodel);
        metamodel.activationConfiguration = V1_buildMemSQLDeploymentConfiguration(element.activationConfiguration, this.context);
        metamodel.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        metamodel.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
    }
    visit_SnowflakeM2MUdf(element) {
        const metamodel = this.context.currentSubGraph.getOwnFunctionActivator(V1_buildFullPath(element.package, element.name));
        metamodel.function = PackageableElementExplicitReference.create(guaranteeNonNullable(this.context.graph.functions.find((fn) => generateFunctionPrettyName(fn, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }) === element.function.path.replaceAll(/\s*/gu, ''))));
        metamodel.ownership = V1_buildDeploymentOwnership(element.ownership, metamodel);
        metamodel.activationConfiguration =
            V1_buildSnowflakeM2MUdfDeploymentConfiguration(element.activationConfiguration, this.context);
        metamodel.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        metamodel.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
    }
    visit_HostedService(element) {
        assertNonEmptyString(element.pattern, `Hosted Service 'pattern' field is missing or empty`);
        const metamodel = this.context.currentSubGraph.getOwnFunctionActivator(V1_buildFullPath(element.package, element.name));
        metamodel.function = PackageableElementExplicitReference.create(guaranteeNonNullable(this.context.graph.functions.find((fn) => generateFunctionPrettyName(fn, {
            fullPath: true,
            spacing: false,
            notIncludeParamName: true,
        }) === element.function.path.replaceAll(/\s*/gu, ''))));
        metamodel.ownership = V1_builHostedServiceOwnership(element.ownership, metamodel);
        if (element.activationConfiguration) {
            metamodel.activationConfiguration =
                V1_buildHostedServiceDeploymentConfiguration(element.activationConfiguration);
        }
        metamodel.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        metamodel.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
        metamodel.actions = element.actions
            .map((action) => V1_buildHostedServiceActions(action, this.context))
            .filter(isNonNullable);
    }
    visit_INTERNAL__UnknownStore(element) {
        return;
    }
    visit_Profile(element) {
        const profile = this.context.currentSubGraph.getOwnProfile(V1_buildFullPath(element.package, element.name));
        const uniqueStereotypes = new Set();
        profile.p_stereotypes = element.stereotypes.map((stereotypeV) => {
            const stereotype = stereotypeV.value;
            if (uniqueStereotypes.has(stereotype)) {
                const message = `Found duplicated stereotype '${stereotype}' in profile '${element.path}'`;
                /**
                 * In strict-mode, graph builder will consider this as an error
                 * See https://github.com/finos/legend-studio/issues/941
                 *
                 * @discrepancy graph-building
                 */
                if (this.context.options?.strict) {
                    throw new GraphBuilderError(message);
                }
                this.context.logService.warn(LogEvent.create(message));
            }
            uniqueStereotypes.add(stereotype);
            return new Stereotype(profile, stereotype);
        });
        const uniqueTags = new Set();
        profile.p_tags = element.tags.map((tagV) => {
            const tag = tagV.value;
            if (uniqueTags.has(tag)) {
                const message = `Found duplicated tag '${tag}' in profile '${element.path}'`;
                /**
                 * In strict-mode, graph builder will consider this as an error
                 * See https://github.com/finos/legend-studio/issues/941
                 *
                 * @discrepancy graph-building
                 */
                if (this.context.options?.strict) {
                    throw new GraphBuilderError(message);
                }
                this.context.logService.warn(LogEvent.create(message));
            }
            uniqueTags.add(tag);
            return new Tag(profile, tag);
        });
    }
    visit_Enumeration(element) {
        const enumeration = this.context.currentSubGraph.getOwnEnumeration(V1_buildFullPath(element.package, element.name));
        enumeration.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        enumeration.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
        const uniqueEnumValues = new Set();
        enumeration.values = element.values.map((enumValue) => {
            assertNonEmptyString(enumValue.value, `Enum value 'value' field is missing or empty`);
            if (uniqueEnumValues.has(enumValue.value)) {
                const message = `Found duplicated value '${enumValue.value}' in enumeration '${enumeration.path}'`;
                /**
                 * In strict-mode, graph builder will consider this as an error
                 * See https://github.com/finos/legend-studio/issues/941
                 *
                 * @discrepancy graph-building
                 */
                if (this.context.options?.strict) {
                    throw new GraphBuilderError(message);
                }
                this.context.logService.warn(LogEvent.create(message));
            }
            const _enum = new Enum(enumValue.value, enumeration);
            _enum.stereotypes = enumValue.stereotypes
                .map((stereotype) => this.context.resolveStereotype(stereotype))
                .filter(isNonNullable);
            _enum.taggedValues = enumValue.taggedValues
                .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
                .filter(isNonNullable);
            uniqueEnumValues.add(enumValue.value);
            return _enum;
        });
    }
    visit_Measure(element) {
        assertNonNullable(element.canonicalUnit, `Measure 'canonicalUnit' field is missing`);
        const measure = this.context.currentSubGraph.getOwnMeasure(V1_buildFullPath(element.package, element.name));
        measure.canonicalUnit = V1_buildUnit(element.canonicalUnit, measure, this.context.graph, this.context);
        measure.nonCanonicalUnits = element.nonCanonicalUnits.map((unit) => V1_buildUnit(unit, measure, this.context.currentSubGraph, this.context));
    }
    visit_Class(element) {
        const _class = this.context.currentSubGraph.getOwnClass(V1_buildFullPath(element.package, element.name));
        _class.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        _class.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
    }
    visit_Association(element) {
        throw new UnsupportedOperationError();
    }
    // NOTE: Alloy Execution server has 2 passes for processing as it needs to build the lambda and compiles
    // but we currently do not build the lambda and so this needs only one pass
    visit_ConcreteFunctionDefinition(protocol) {
        assertNonNullable(protocol.returnGenericType, `Function 'returnGenericType' field is missing or empty`);
        assertNonNullable(protocol.returnMultiplicity, `Function 'returnMultiplicity' field is missing`);
        const func = this.context.currentSubGraph.getOwnFunction(V1_buildFullPath(protocol.package, V1_buildFunctionSignature(protocol)));
        func.returnType =
            this.context.resolveGenericTypeFromProtocolWithRelationType(protocol.returnGenericType);
        func.returnMultiplicity = this.context.graph.getMultiplicity(protocol.returnMultiplicity.lowerBound, protocol.returnMultiplicity.upperBound);
        func.stereotypes = protocol.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        func.taggedValues = protocol.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
        func.parameters = protocol.parameters.map((param) => V1_buildVariable(param, this.context));
        func.expressionSequence = protocol.body;
        func.functionName = getFunctionName(func, func.name);
        if (protocol.tests?.length) {
            func.tests = protocol.tests.map((l) => V1_buildFunctionSuite(l, this.context));
        }
    }
    visit_FlatData(element) {
        const flatData = this.context.currentSubGraph.getOwnFlatDataStore(V1_buildFullPath(element.package, element.name));
        flatData.sections = element.sections.map((section) => V1_buildFlatDataSection(section, flatData, this.context));
    }
    visit_Database(element) {
        const database = this.context.currentSubGraph.getOwnDatabase(V1_buildFullPath(element.package, element.name));
        database.includes = element.includedStores.map((includedStore) => this.context.resolveDatabase(includedStore.path));
        database.includedStoreSpecifications =
            element.includedStoreSpecifications.map((v1IncludeStore) => {
                const storePath = v1IncludeStore.packageableElementPointer.path;
                const storeElement = guaranteeNonNullable(returnUndefOnError(() => this.context.graph.getIngestDefinition(storePath)) ??
                    returnUndefOnError(() => this.context.graph.getDataProduct(storePath)), `Ingest/Data Product ${storePath} not found`);
                const includedStore = new IncludeStore(PackageableElementImplicitReference.create(storeElement, storePath), v1IncludeStore.storeType);
                V1_initInternalLakehouseGeneratedDatabase(includedStore, database);
                return includedStore;
            });
        database.schemas = element.schemas.map((schema) => V1_buildSchema(schema, database, this.context));
    }
    getMappingIdentifier(protocol) {
        if (protocol instanceof V1_INTERNAL__UnknownMappingInclude) {
            return undefined;
        }
        if (protocol instanceof V1_MappingIncludeDataProduct) {
            const dataProduct = this.context.graph.getDataProduct(protocol.includedDataProduct);
            return guaranteeNonNullable(dataProduct.accessPointGroups
                .filter((apg) => apg instanceof ModelAccessPointGroup)
                .at(0), `include dataproduct requires Model AccessPoint Group. Can't find a Model AccessPoint Group for the dataproduct ${protocol.includedDataProduct}`).mapping.value.path;
        }
        if (protocol instanceof V1_MappingIncludeMapping) {
            return protocol.includedMapping;
        }
        const extraIncludeMappingIdentifierBuilders = this.context.extensions.plugins.flatMap((plugin) => plugin.V1_getExtraMappingIncludeIdentifierBuilders?.() ?? []);
        for (const builder of extraIncludeMappingIdentifierBuilders) {
            const builtIdentifier = builder(protocol);
            if (builtIdentifier) {
                return builtIdentifier;
            }
        }
        throw new UnsupportedOperationError(`Can't build mapping include identifier: no compatible builder available from plugins`, protocol);
    }
    visit_Mapping(element) {
        const mapping = this.context.currentSubGraph.getOwnMapping(V1_buildFullPath(element.package, element.name));
        const mappingIncludesSet = new Set();
        mapping.includes = element.includedMappings.map((mappingInclude) => {
            const includedMappingIdentifier = this.getMappingIdentifier(mappingInclude);
            if (includedMappingIdentifier) {
                assertTrue(!mappingIncludesSet.has(includedMappingIdentifier), `Duplicated mapping include '${includedMappingIdentifier}' in mapping '${mapping.path}'`);
                mappingIncludesSet.add(includedMappingIdentifier);
            }
            return V1_buildMappingInclude(mappingInclude, this.context, mapping);
        });
        mapping.enumerationMappings = element.enumerationMappings.map((enumerationMapping) => V1_buildEnumerationMapping(enumerationMapping, this.context, mapping));
    }
    visit_Service(element) {
        assertNonEmptyString(element.pattern, `Service 'pattern' field is missing or empty`);
        const service = this.context.currentSubGraph.getOwnService(V1_buildFullPath(element.package, element.name));
        service.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        service.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
        service.pattern = element.pattern;
        service.owners = element.owners.slice();
        service.documentation = element.documentation;
        service.autoActivateUpdates = element.autoActivateUpdates;
        service.mcpServer = element.mcpServer;
        if (element.ownership) {
            service.ownership = V1_buildServiceOwnership(element.ownership, service);
        }
        // NOTE: process execution before the test, so we can do some check between test and execution (such matching type, keys, etc.)
        service.execution = V1_buildServiceExecution(element.execution, this.context, service);
        if (element.test) {
            service.test = V1_buildLegacyServiceTest(element.test, this.context, service);
        }
        service.tests = element.testSuites
            .map((testSuite) => V1_buildTestSuite(service, testSuite, this.context))
            .map((e) => guaranteeType(e, ServiceTestSuite));
        service.postValidations = element.postValidations
            .map((postValidation) => V1_buildPostValidation(postValidation, this.context))
            .map((e) => guaranteeType(e, PostValidation));
    }
    visit_SectionIndex(element) {
        const sectionIndex = this.context.currentSubGraph.getOwnSectionIndex(element.path);
        sectionIndex.sections = element.sections.map((section) => V1_buildSection(section, this.context, sectionIndex));
    }
    visit_FileGeneration(element) {
        assertNonEmptyString(element.type, `File generation 'type' field is missing or empty`);
        const fileGeneration = this.context.currentSubGraph.getOwnFileGeneration(V1_buildFullPath(element.package, element.name));
        fileGeneration.type = element.type;
        fileGeneration.configurationProperties =
            element.configurationProperties.map(V1_buildConfigurationProperty);
        fileGeneration.generationOutputPath = element.generationOutputPath;
        fileGeneration.scopeElements = element.scopeElements.map((scopeElement) => V1_buildScopeElement(scopeElement, this.context));
    }
    visit_GenerationSpecification(element) {
        const generationSpec = this.context.currentSubGraph.getOwnGenerationSpecification(V1_buildFullPath(element.package, element.name));
        generationSpec.generationNodes = element.generationNodes.map((node) => V1_buildGenerationTreeNode(node, this.context));
        generationSpec.fileGenerations = element.fileGenerations.map((node) => V1_buildFileGenerationPointer(node, this.context));
    }
    visit_PackageableRuntime(element) {
        const runtime = this.context.currentSubGraph.getOwnRuntime(V1_buildFullPath(element.package, element.name));
        runtime.runtimeValue = V1_buildEngineRuntime(element.runtimeValue, this.context);
    }
    visit_PackageableConnection(element) {
        const connection = this.context.currentSubGraph.getOwnConnection(V1_buildFullPath(element.package, element.name));
        if (element.connectionValue instanceof V1_ConnectionPointer) {
            throw new IllegalStateError('Packageable connection value cannot be a connection pointer');
        }
        connection.connectionValue = V1_buildConnection(element.connectionValue, this.context);
    }
    visit_DataElement(element) {
        const dataElement = this.context.currentSubGraph.getOwnDataElement(V1_buildFullPath(element.package, element.name));
        dataElement.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        dataElement.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
        if (element.data instanceof V1_DataElementReference) {
            throw new IllegalStateError('Cannot use Data element reference in a Data element');
        }
        dataElement.data = V1_buildEmbeddedData(element.data, this.context);
    }
    visit_ExecutionEnvironmentInstance(element) {
        const execEnv = this.context.currentSubGraph.getOwnExecutionEnvironment(V1_buildFullPath(element.package, element.name));
        execEnv.executionParameters = element.executionParameters.map((e) => V1_buildExecutionParameters(e, this.context));
    }
    visit_DataProduct(element) {
        const dataProduct = this.context.currentSubGraph.getOwnDataProduct(V1_buildFullPath(element.package, element.name));
        dataProduct.title = element.title;
        dataProduct.description = element.description;
        if (element.icon) {
            dataProduct.icon = V1_buildDataProductIcon(element.icon);
        }
        dataProduct.accessPointGroups = element.accessPointGroups.map((gr) => V1_buildAccessPointGroup(gr, this.context));
        if (element.nativeModelAccess) {
            dataProduct.nativeModelAccess = V1_buildNativeModelAccess(element.nativeModelAccess, this.context);
        }
        const protocolSupportInfo = element.supportInfo;
        if (protocolSupportInfo) {
            const supportInfo = new SupportInfo();
            supportInfo.documentation = protocolSupportInfo.documentation
                ? V1_buildDataProductLink(protocolSupportInfo.documentation)
                : undefined;
            supportInfo.website = protocolSupportInfo.website
                ? V1_buildDataProductLink(protocolSupportInfo.website)
                : undefined;
            supportInfo.faqUrl = protocolSupportInfo.faqUrl
                ? V1_buildDataProductLink(protocolSupportInfo.faqUrl)
                : undefined;
            supportInfo.supportUrl = protocolSupportInfo.supportUrl
                ? V1_buildDataProductLink(protocolSupportInfo.supportUrl)
                : undefined;
            supportInfo.expertise =
                protocolSupportInfo.expertise?.map((expertise) => V1_buildDataProductExpertise(expertise)) ?? [];
            supportInfo.emails = protocolSupportInfo.emails.map((elementEmail) => {
                const email = new Email(elementEmail.address, elementEmail.title);
                return email;
            });
            dataProduct.supportInfo = supportInfo;
        }
        if (element.type instanceof V1_InternalDataProductType) {
            dataProduct.type = new InternalDataProductType();
        }
        else if (element.type instanceof V1_ExternalDataProductType) {
            const dataProductType = new ExternalDataProductType();
            dataProductType.link = element.type.link;
            dataProduct.type = dataProductType;
        }
        dataProduct.sampleValues = element.sampleValues?.map((data) => V1_buildEmbeddedData(data, this.context));
        if (element.operationalMetadata) {
            dataProduct.operationalMetadata = V1_buildDataProductOperationalMetadata(element.operationalMetadata);
        }
        dataProduct.stereotypes = element.stereotypes
            .map((stereotype) => this.context.resolveStereotype(stereotype))
            .filter(isNonNullable);
        dataProduct.taggedValues = element.taggedValues
            .map((taggedValue) => V1_buildTaggedValue(taggedValue, this.context))
            .filter(isNonNullable);
    }
}
//# sourceMappingURL=V1_ElementSecondPassBuilder.js.map