import { mapValues } from '../runtime{{importFileExtension}}';
{{#hasImports}}
{{#tsImports}}
import type { {{{classname}}} } from './{{filename}}{{importFileExtension}}';
import {
    {{classname}}FromJSON,
    {{classname}}FromJSONTyped,
    {{classname}}ToJSON,
    {{classname}}ToJSONTyped,
} from './{{filename}}{{importFileExtension}}';
{{/tsImports}}

{{/hasImports}}
{{#discriminator}}
{{#discriminator.mappedModels}}
import { type {{modelName}}, {{modelName}}FromJSONTyped, {{modelName}}ToJSON, {{modelName}}ToJSONTyped } from './{{modelName}}{{importFileExtension}}';
{{/discriminator.mappedModels}}
{{/discriminator}}
{{>modelGenericInterfaces}}


/**
 * Check if a given object implements the {{classname}} interface.
 */
export function instanceOf{{classname}}(value: object): value is {{classname}} {
    {{#vars}}
    {{#required}}
    if (!('{{name}}' in value) || value['{{name}}'] === undefined) return false;
    {{! START CUSTOM TEMPLATING FOR synapse-client }}
    {{! if the property is a required enum, check that the value is a valid enum value }}
    {{#isEnum}}
    if (!Object.values({{classname}}{{enumName}}).includes(value["{{name}}"] as {{classname}}{{enumName}})) {
      return false
    }
    {{/isEnum}}
    {{! END CUSTOM TEMPLATING FOR synapse-client }}
    {{/required}}
    {{/vars}}
    return true;
}

export function {{classname}}FromJSON(json: any): {{classname}} {
    return {{classname}}FromJSONTyped(json, false);
}

export function {{classname}}FromJSONTyped(json: any, ignoreDiscriminator: boolean): {{classname}} {
    {{#hasVars}}
    if (json == null) {
        return json;
    }
{{#discriminator}}
    if (!ignoreDiscriminator) {
{{#discriminator.mappedModels}}
        if (json['{{discriminator.propertyBaseName}}'] === '{{mappingName}}') {
            return {{modelName}}FromJSONTyped(json, ignoreDiscriminator);
        }
{{/discriminator.mappedModels}}
    }
{{/discriminator}}
    return {
        {{#parent}}...{{{.}}}FromJSONTyped(json, true),{{/parent}}
        {{#additionalPropertiesType}}
            ...json,
        {{/additionalPropertiesType}}
        {{#vars}}
        {{#isPrimitiveType}}
        {{#isArray}}
        {{#uniqueItems}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}{{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{/required}}new Set(json['{{baseName}}']),
        {{/uniqueItems}}
        {{^uniqueItems}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}{{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{/required}}json['{{baseName}}'],
        {{/uniqueItems}}
        {{/isArray}}
        {{^isArray}}
        {{#isDateType}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{/required}}new Date(json['{{baseName}}'])),
        {{/isDateType}}
        {{#isDateTimeType}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{/required}}new Date(json['{{baseName}}'])),
        {{/isDateTimeType}}
        {{^isDateType}}
        {{^isDateTimeType}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}json['{{baseName}}'],
        {{/isDateTimeType}}
        {{/isDateType}}
        {{/isArray}}
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
        {{#isArray}}
        {{#uniqueItems}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{/required}}new Set((json['{{baseName}}'] as Array<any>).map({{#items}}{{datatype}}{{/items}}FromJSON))),
        {{/uniqueItems}}
        {{^uniqueItems}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{/required}}(json['{{baseName}}'] as Array<any>).map({{#items}}{{datatype}}{{/items}}FromJSON)),
        {{/uniqueItems}}
        {{/isArray}}
        {{#isMap}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{/required}}mapValues(json['{{baseName}}'], {{#items}}{{datatype}}{{/items}}FromJSON)),
        {{/isMap}}
        {{^isArray}}
        {{^isMap}}
        {{^isFreeFormObject}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}{{datatype}}FromJSON(json['{{baseName}}']),
        {{/isFreeFormObject}}
        {{#isFreeFormObject}}
        '{{name}}': {{^required}}json['{{baseName}}'] == null ? undefined : {{/required}}json['{{baseName}}'],
        {{/isFreeFormObject}}
        {{/isMap}}
        {{/isArray}}
        {{/isPrimitiveType}}
        {{/vars}}
    };
    {{/hasVars}}
    {{^hasVars}}
    return json;
    {{/hasVars}}
}

export function {{classname}}ToJSON(json: any): {{classname}} {
    return {{classname}}ToJSONTyped(json, false);
}

export function {{classname}}ToJSONTyped(value?: {{#hasReadOnly}}Omit<{{classname}}, {{#readOnlyVars}}'{{baseName}}'{{^-last}}|{{/-last}}{{/readOnlyVars}}>{{/hasReadOnly}}{{^hasReadOnly}}{{classname}}{{/hasReadOnly}} | null, ignoreDiscriminator: boolean = false): any {
    {{#hasVars}}
    if (value == null) {
        return value;
    }
    {{#discriminator}}

    if (!ignoreDiscriminator) {
        switch (value['{{discriminator.propertyName}}']) {
        {{#discriminator.mappedModels}}
            case '{{mappingName}}':
                return {{modelName}}ToJSONTyped(value as {{modelName}}, ignoreDiscriminator);
        {{/discriminator.mappedModels}}
            default:
                return value;
        }
    }
    {{/discriminator}}

    return {
        {{#parent}}...{{{.}}}ToJSONTyped(value, true),{{/parent}}
        {{#additionalPropertiesType}}
            ...value,
        {{/additionalPropertiesType}}
        {{#vars}}
        {{^isReadOnly}}
        {{#isPrimitiveType}}
        {{#isDateType}}
        '{{baseName}}': {{^required}}{{#isNullable}}value['{{name}}'] === null ? null : {{/isNullable}}{{^isNullable}}value['{{name}}'] == null ? undefined : {{/isNullable}}{{/required}}((value['{{name}}']{{#isNullable}} as any{{/isNullable}}){{^required}}{{#isNullable}}?{{/isNullable}}{{/required}}.toISOString().substring(0,10)),
        {{/isDateType}}
        {{#isDateTimeType}}
        '{{baseName}}': {{^required}}{{#isNullable}}value['{{name}}'] === null ? null : {{/isNullable}}{{^isNullable}}value['{{name}}'] == null ? undefined : {{/isNullable}}{{/required}}((value['{{name}}']{{#isNullable}} as any{{/isNullable}}){{^required}}{{#isNullable}}?{{/isNullable}}{{/required}}.toISOString()),
        {{/isDateTimeType}}
        {{#isArray}}
        '{{baseName}}': {{#uniqueItems}}{{^required}}value['{{name}}'] == null ? undefined : {{/required}}{{#required}}{{#isNullable}}value['{{name}}'] == null ? null : {{/isNullable}}{{/required}}Array.from(value['{{name}}'] as Set<any>){{/uniqueItems}}{{^uniqueItems}}value['{{name}}']{{/uniqueItems}},
        {{/isArray}}
        {{^isDateType}}
        {{^isDateTimeType}}
        {{^isArray}}
        '{{baseName}}': value['{{name}}'],
        {{/isArray}}
        {{/isDateTimeType}}
        {{/isDateType}}
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
        {{#isArray}}
        {{#uniqueItems}}
        '{{baseName}}': {{^required}}value['{{name}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}value['{{name}}'] == null ? null : {{/isNullable}}{{/required}}Array.from(value['{{name}}'] as Set<any>).map({{#items}}{{datatype}}{{/items}}ToJSON)),
        {{/uniqueItems}}
        {{^uniqueItems}}
        '{{baseName}}': {{^required}}value['{{name}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}value['{{name}}'] == null ? null : {{/isNullable}}{{/required}}(value['{{name}}'] as Array<any>).map({{#items}}{{datatype}}{{/items}}ToJSON)),
        {{/uniqueItems}}
        {{/isArray}}
        {{#isMap}}
        '{{baseName}}': {{^required}}value['{{name}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}value['{{name}}'] == null ? null : {{/isNullable}}{{/required}}mapValues(value['{{name}}'], {{#items}}{{datatype}}{{/items}}ToJSON)),
        {{/isMap}}
        {{^isArray}}
        {{^isMap}}
        {{^isFreeFormObject}}
        '{{baseName}}': {{datatype}}ToJSON(value['{{name}}']),
        {{/isFreeFormObject}}
        {{#isFreeFormObject}}
        '{{baseName}}': value['{{name}}'],
        {{/isFreeFormObject}}
        {{/isMap}}
        {{/isArray}}
        {{/isPrimitiveType}}
        {{/isReadOnly}}
        {{/vars}}
    };
    {{/hasVars}}
    {{^hasVars}}
    return value;
    {{/hasVars}}
}
{{#validationAttributes}}

export const {{classname}}PropertyValidationAttributesMap: {
    [property: string]: {
        maxLength?: number,
        minLength?: number,
        pattern?: string,
        maximum?: number,
        exclusiveMaximum?: boolean,
        minimum?: number,
        exclusiveMinimum?: boolean,
        multipleOf?: number,
        maxItems?: number,
        minItems?: number,
        uniqueItems?: boolean
    }
} = {
{{#vars}}
{{#hasValidation}}
    {{name}}: {
        {{#maxLength}}
        maxLength: {{maxLength}},
        {{/maxLength}}
        {{#minLength}}
        minLength: {{minLength}},
        {{/minLength}}
        {{#pattern}}
        pattern: '{{pattern}}',
        {{/pattern}}
        {{#maximum}}
        maximum: {{maximum}},
        exclusiveMaximum: {{exclusiveMaximum}},
        {{/maximum}}
        {{#minimum}}
        minimum: {{minimum}},
        exclusiveMinimum: {{exclusiveMinimum}},
        {{/minimum}}
        {{#multipleOf}}
        multipleOf: {{multipleOf}},
        {{/multipleOf}}
        {{#maxItems}}
        maxItems: {{maxItems}},
        {{/maxItems}}
        {{#minItems}}
        minItems: {{minItems}},
        {{/minItems}}
        {{#isArray}}
        uniqueItems: {{uniqueItems}},
        {{/isArray}}
    },
{{/hasValidation}}
{{/vars}}
}
{{#isAdditionalPropertiesTrue}}

export const {{classname}}AdditionalPropertiesValidationAttributes: { maxProperties?: number, minProperties?: number } = {
    {{#maxProperties}}
    maxProperties: {{maxProperties}},
    {{/maxProperties}}
    {{#minProperties}}
    minProperties: {{minProperties}},
    {{/minProperties}}
}
{{/isAdditionalPropertiesTrue}}
{{/validationAttributes}}
