/**
 * 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 { createModelSchema, deserialize, list, optional, primitive, serialize, } from 'serializr';
import { V1_AccessPointGroup, V1_DATA_PRODUCT_ELEMENT_PROTOCOL_TYPE, V1_DataProduct, V1_DataProductDiagram, V1_DataProductEmbeddedImageIcon, V1_DataProductLibraryIcon, V1_DataProductLink, V1_DataProductRuntimeInfo, V1_ElementScope, V1_Email, V1_LakehouseAccessPoint, V1_ModelAccessPointGroup, V1_SupportInfo, V1_UnknownAccessPoint, V1_UnknownDataProductIcon, V1_InternalDataProductType, V1_ExternalDataProductType, V1_DataProductTypeValue, V1_Expertise, V1_FunctionAccessPoint, V1_DataProductOperationalMetadata, V1_NativeModelAccess, V1_PackageableElementSampleQuery, V1_InLineSampleQuery, V1_NativeModelExecutionContext, } from '../../../model/packageableElements/dataProduct/V1_DataProduct.js';
import { UnsupportedOperationError, usingConstantValueSchema, usingModelSchema, customList, customListWithSchema, optionalCustomUsingModelSchema, optionalCustom, optionalCustomList, optionalCustomListWithSchema, } from '@finos/legend-shared';
import { V1_rawLambdaModelSchema } from './V1_RawValueSpecificationSerializationHelper.js';
import { V1_packageableElementPointerModelSchema, V1_stereotypePtrModelSchema, V1_taggedValueModelSchema, } from './V1_CoreSerializationHelper.js';
import { V1_MappingIncludeDataProduct } from '../../../model/packageableElements/dataProduct/V1_MappingIncludeDataProduct.js';
import { V1_deserializeEmbeddedDataType, V1_serializeEmbeddedDataType, } from './V1_DataElementSerializationHelper.js';
export var V1_AccessPointType;
(function (V1_AccessPointType) {
    V1_AccessPointType["LAKEHOUSE"] = "lakehouseAccessPoint";
    V1_AccessPointType["FUNCTION"] = "functionAccessPoint";
    V1_AccessPointType["EQUAL_TO_JSON"] = "equalToJson";
    V1_AccessPointType["EQUAL_TO_TDS"] = "equalToTDS";
})(V1_AccessPointType || (V1_AccessPointType = {}));
export var V1_AccessPointGrouptype;
(function (V1_AccessPointGrouptype) {
    V1_AccessPointGrouptype["DEFAULT_ACCESS_POINT_GROUP"] = "defaultAccessPointGroup";
    V1_AccessPointGrouptype["MODEL_ACCESS_POINT_GROUP"] = "modelAccessPointGroup";
})(V1_AccessPointGrouptype || (V1_AccessPointGrouptype = {}));
export var V1_SampleQueryType;
(function (V1_SampleQueryType) {
    V1_SampleQueryType["IN_LINE_SAMPLE_QUERY"] = "inLineSampleQuery";
    V1_SampleQueryType["PACKAGEABLE_ELEMENT_SAMPLE_QUERY"] = "packageableElementSampleQuery";
})(V1_SampleQueryType || (V1_SampleQueryType = {}));
export var V1_DataProductIconType;
(function (V1_DataProductIconType) {
    V1_DataProductIconType["LIBRARY_ICON"] = "libraryIcon";
    V1_DataProductIconType["EMBEDDED_IMAGE_ICON"] = "embeddedImageIcon";
})(V1_DataProductIconType || (V1_DataProductIconType = {}));
export var V1_DataProductIconLibraryId;
(function (V1_DataProductIconLibraryId) {
    V1_DataProductIconLibraryId["REACT_ICONS"] = "react-icons";
})(V1_DataProductIconLibraryId || (V1_DataProductIconLibraryId = {}));
export const V1_lakehouseAccessPointModelSchema = createModelSchema(V1_LakehouseAccessPoint, {
    _type: usingConstantValueSchema(V1_AccessPointType.LAKEHOUSE),
    classification: optional(primitive()),
    description: optional(primitive()),
    func: usingModelSchema(V1_rawLambdaModelSchema),
    id: primitive(),
    reproducible: optional(primitive()),
    stereotypes: customListWithSchema(V1_stereotypePtrModelSchema, {
        INTERNAL__forceReturnEmptyInTest: true,
    }),
    targetEnvironment: primitive(),
    title: optional(primitive()),
});
export const V1_functionAccessPointModelSchema = createModelSchema(V1_FunctionAccessPoint, {
    _type: usingConstantValueSchema(V1_AccessPointType.FUNCTION),
    description: optional(primitive()),
    id: primitive(),
    query: usingModelSchema(V1_rawLambdaModelSchema),
    stereotypes: customListWithSchema(V1_stereotypePtrModelSchema, {
        INTERNAL__forceReturnEmptyInTest: true,
    }),
    title: optional(primitive()),
});
const V1_serializeAccessPoint = (protocol) => {
    if (protocol instanceof V1_LakehouseAccessPoint) {
        return serialize(V1_lakehouseAccessPointModelSchema, protocol);
    }
    else if (protocol instanceof V1_UnknownAccessPoint) {
        return protocol.content;
    }
    else if (protocol instanceof V1_FunctionAccessPoint) {
        return serialize(V1_functionAccessPointModelSchema, protocol);
    }
    throw new UnsupportedOperationError(`Can't serialize access point type`, protocol);
};
const V1_deserializeAccessPoint = (json) => {
    switch (json._type) {
        case V1_AccessPointType.LAKEHOUSE:
            return deserialize(V1_lakehouseAccessPointModelSchema, json);
        case V1_AccessPointType.FUNCTION:
            return deserialize(V1_functionAccessPointModelSchema, json);
        default: {
            const unknown = new V1_UnknownAccessPoint();
            unknown.content = json;
            unknown.id = json.id;
            unknown.description = json.description;
            unknown.title = json.title;
            return unknown;
        }
    }
};
export const V1_DataProductRuntimeInfoModelSchema = createModelSchema(V1_DataProductRuntimeInfo, {
    description: optional(primitive()),
    id: primitive(),
    runtime: usingModelSchema(V1_packageableElementPointerModelSchema),
});
export const V1_dataProductDiagramModelSchema = createModelSchema(V1_DataProductDiagram, {
    title: primitive(),
    description: optional(primitive()),
    diagram: usingModelSchema(V1_packageableElementPointerModelSchema),
});
export const V1_ElementScopeModelSchema = createModelSchema(V1_ElementScope, {
    element: usingModelSchema(V1_packageableElementPointerModelSchema),
    exclude: optional(primitive()),
});
export const V1_ModelAccessPointGroupModelSchema = createModelSchema(V1_ModelAccessPointGroup, {
    _type: usingConstantValueSchema(V1_AccessPointGrouptype.MODEL_ACCESS_POINT_GROUP),
    accessPoints: customList(V1_serializeAccessPoint, V1_deserializeAccessPoint),
    description: optional(primitive()),
    diagrams: customListWithSchema(V1_dataProductDiagramModelSchema),
    featuredElements: customListWithSchema(V1_ElementScopeModelSchema),
    id: primitive(),
    title: optional(primitive()),
    stereotypes: customListWithSchema(V1_stereotypePtrModelSchema),
    mapping: usingModelSchema(V1_packageableElementPointerModelSchema),
});
export const V1_PackageableElementSampleQueryModelSchema = createModelSchema(V1_PackageableElementSampleQuery, {
    _type: usingConstantValueSchema(V1_SampleQueryType.PACKAGEABLE_ELEMENT_SAMPLE_QUERY),
    description: optional(primitive()),
    executionContextKey: optional(primitive()),
    id: primitive(),
    query: usingModelSchema(V1_packageableElementPointerModelSchema),
    title: primitive(),
});
export const V1_InLineSampleQueryModelSchema = createModelSchema(V1_InLineSampleQuery, {
    _type: usingConstantValueSchema(V1_SampleQueryType.IN_LINE_SAMPLE_QUERY),
    description: optional(primitive()),
    executionContextKey: optional(primitive()),
    id: primitive(),
    query: usingModelSchema(V1_rawLambdaModelSchema),
    title: primitive(),
});
const V1_serializeSampleQuery = (protocol) => {
    if (protocol instanceof V1_InLineSampleQuery) {
        return serialize(V1_InLineSampleQueryModelSchema, protocol);
    }
    else if (protocol instanceof V1_PackageableElementSampleQuery) {
        return serialize(V1_PackageableElementSampleQueryModelSchema, protocol);
    }
    throw new UnsupportedOperationError(`Can't serialize data product sample query`, protocol);
};
export const V1_deserializeSampleQuery = (json) => {
    switch (json._type) {
        case V1_SampleQueryType.IN_LINE_SAMPLE_QUERY:
            return deserialize(V1_InLineSampleQueryModelSchema, json);
        case V1_SampleQueryType.PACKAGEABLE_ELEMENT_SAMPLE_QUERY:
        default:
            return deserialize(V1_PackageableElementSampleQueryModelSchema, json);
    }
};
export const V1_NativeModelExecutionContextSchema = createModelSchema(V1_NativeModelExecutionContext, {
    key: primitive(),
    mapping: usingModelSchema(V1_packageableElementPointerModelSchema),
    runtime: optionalCustomUsingModelSchema(V1_packageableElementPointerModelSchema),
});
export const V1_NativeModelAccessModelSchema = createModelSchema(V1_NativeModelAccess, {
    diagrams: optionalCustomListWithSchema(V1_dataProductDiagramModelSchema),
    defaultExecutionContext: primitive(),
    featuredElements: optionalCustomListWithSchema(V1_ElementScopeModelSchema),
    nativeModelExecutionContexts: customListWithSchema(V1_NativeModelExecutionContextSchema),
    sampleQueries: optionalCustomList((val) => V1_serializeSampleQuery(val), (val) => V1_deserializeSampleQuery(val)),
});
export const V1_DefaultAccessPointGroupModelSchema = createModelSchema(V1_AccessPointGroup, {
    _type: usingConstantValueSchema(V1_AccessPointGrouptype.DEFAULT_ACCESS_POINT_GROUP),
    accessPoints: customList(V1_serializeAccessPoint, V1_deserializeAccessPoint),
    description: optional(primitive()),
    id: primitive(),
    title: optional(primitive()),
    stereotypes: customListWithSchema(V1_stereotypePtrModelSchema, {
        INTERNAL__forceReturnEmptyInTest: true,
    }),
});
const V1_serializeAccessPointGroup = (protocol) => {
    if (protocol instanceof V1_ModelAccessPointGroup) {
        return serialize(V1_ModelAccessPointGroupModelSchema, protocol);
    }
    return serialize(V1_DefaultAccessPointGroupModelSchema, protocol);
};
const V1_deserializeAccessPointGroup = (json) => {
    switch (json._type) {
        case V1_AccessPointGrouptype.MODEL_ACCESS_POINT_GROUP:
            return deserialize(V1_ModelAccessPointGroupModelSchema, json);
        default: {
            return deserialize(V1_DefaultAccessPointGroupModelSchema, json);
        }
    }
};
export const V1_DataProductLibraryIconModelSchema = createModelSchema(V1_DataProductLibraryIcon, {
    _type: usingConstantValueSchema(V1_DataProductIconType.LIBRARY_ICON),
    iconId: primitive(),
    libraryId: primitive(),
});
export const V1_DataProductEmbeddedImageIconModelSchema = createModelSchema(V1_DataProductEmbeddedImageIcon, {
    _type: usingConstantValueSchema(V1_DataProductIconType.EMBEDDED_IMAGE_ICON),
    imageUrl: primitive(),
});
const V1_deserializeDataProductIcon = (json) => {
    switch (json._type) {
        case V1_DataProductIconType.LIBRARY_ICON:
            return deserialize(V1_DataProductLibraryIconModelSchema, json);
        case V1_DataProductIconType.EMBEDDED_IMAGE_ICON:
            return deserialize(V1_DataProductEmbeddedImageIconModelSchema, json);
        default: {
            const unknown = new V1_UnknownDataProductIcon();
            unknown.content = json;
            return unknown;
        }
    }
};
const V1_serializeDataProductIcon = (protocol) => {
    if (protocol instanceof V1_DataProductLibraryIcon) {
        return serialize(V1_DataProductLibraryIconModelSchema, protocol);
    }
    else if (protocol instanceof V1_DataProductEmbeddedImageIcon) {
        return serialize(V1_DataProductEmbeddedImageIconModelSchema, protocol);
    }
    throw new UnsupportedOperationError(`Can't serialize data product icon type`, protocol);
};
export const V1_EmailModelSchema = createModelSchema(V1_Email, {
    address: primitive(),
    title: primitive(),
});
const V1_DataProductLinkModelSchema = createModelSchema(V1_DataProductLink, {
    label: optional(primitive()),
    url: primitive(),
});
export const V1_ExpertiseModelSchema = createModelSchema(V1_Expertise, {
    description: optional(primitive()),
    expertIds: list(primitive()),
});
export const V1_SupportInfoModelSchema = createModelSchema(V1_SupportInfo, {
    documentation: optional(usingModelSchema(V1_DataProductLinkModelSchema)),
    emails: customListWithSchema(V1_EmailModelSchema),
    faqUrl: optional(usingModelSchema(V1_DataProductLinkModelSchema)),
    supportUrl: optional(usingModelSchema(V1_DataProductLinkModelSchema)),
    expertise: optionalCustomListWithSchema(V1_ExpertiseModelSchema),
    website: optional(usingModelSchema(V1_DataProductLinkModelSchema)),
});
export const V1_DataProductOperationalMetadataModelSchema = createModelSchema(V1_DataProductOperationalMetadata, {
    coverageRegions: optionalCustomList((json) => json.toLowerCase(), (json) => json.toUpperCase()),
    updateFrequency: optionalCustom((json) => json.toLowerCase(), (json) => json.toUpperCase()),
});
export const V1_InternalDataProductTypeModelSchema = createModelSchema(V1_InternalDataProductType, {
    _type: usingConstantValueSchema(V1_DataProductTypeValue.INTERNAL),
});
export const V1_ExternalDataProductTypeModelSchema = createModelSchema(V1_ExternalDataProductType, {
    _type: usingConstantValueSchema(V1_DataProductTypeValue.EXTERNAL),
    link: usingModelSchema(V1_DataProductLinkModelSchema),
});
export const V1_deserializeDataProductType = (json) => {
    switch (json._type) {
        case V1_DataProductTypeValue.INTERNAL:
            return deserialize(V1_InternalDataProductTypeModelSchema, json);
        case V1_DataProductTypeValue.EXTERNAL:
            return deserialize(V1_ExternalDataProductTypeModelSchema, json);
        default:
            throw new Error(`Unknown V1_DataProductType type: ${json._type}`);
    }
};
export const V1_serializeDataProductType = (value) => {
    if (value instanceof V1_InternalDataProductType) {
        return serialize(V1_InternalDataProductTypeModelSchema, value);
    }
    else if (value instanceof V1_ExternalDataProductType) {
        return serialize(V1_ExternalDataProductTypeModelSchema, value);
    }
    throw new Error(`Unknown V1_DataProductType instance: ${value}`);
};
export const V1_dataProductModelSchema = (plugins) => createModelSchema(V1_DataProduct, {
    _type: usingConstantValueSchema(V1_DATA_PRODUCT_ELEMENT_PROTOCOL_TYPE),
    accessPointGroups: customList(V1_serializeAccessPointGroup, V1_deserializeAccessPointGroup),
    description: optional(primitive()),
    sampleValues: optionalCustomList((data) => V1_serializeEmbeddedDataType(data, plugins), (data) => V1_deserializeEmbeddedDataType(data, plugins), { INTERNAL__forceReturnEmptyInTest: true }),
    icon: optionalCustom(V1_serializeDataProductIcon, V1_deserializeDataProductIcon),
    name: primitive(),
    nativeModelAccess: optionalCustomUsingModelSchema(V1_NativeModelAccessModelSchema),
    operationalMetadata: optionalCustomUsingModelSchema(V1_DataProductOperationalMetadataModelSchema),
    package: primitive(),
    type: optionalCustom(V1_serializeDataProductType, V1_deserializeDataProductType),
    stereotypes: customListWithSchema(V1_stereotypePtrModelSchema, {
        INTERNAL__forceReturnEmptyInTest: true,
    }),
    supportInfo: optionalCustomUsingModelSchema(V1_SupportInfoModelSchema),
    taggedValues: customListWithSchema(V1_taggedValueModelSchema, {
        INTERNAL__forceReturnEmptyInTest: true,
    }),
    title: optional(primitive()),
});
export const V1_MAPPING_INCLUDE_DATAPRODUCT_TYPE = 'mappingIncludeDataProduct';
export const V1_mappingIncludeDataProductModelSchema = createModelSchema(V1_MappingIncludeDataProduct, {
    _type: usingConstantValueSchema(V1_MAPPING_INCLUDE_DATAPRODUCT_TYPE),
    includedDataProduct: primitive(),
});
//# sourceMappingURL=V1_DataProductSerializationHelper.js.map