"use strict";
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObjectImplementation = void 0;
const codemodel_v3_1 = require("@azure-tools/codemodel-v3");
const codegen_1 = require("@azure-tools/codegen");
const codegen_csharp_1 = require("@azure-tools/codegen-csharp");
const codegen_csharp_2 = require("@azure-tools/codegen-csharp");
const codegen_csharp_3 = require("@azure-tools/codegen-csharp");
const codegen_csharp_4 = require("@azure-tools/codegen-csharp");
const clientruntime_1 = require("../clientruntime");
const primitive_1 = require("./primitive");
class ObjectImplementation {
    get defaultOfType() {
        return (0, codegen_csharp_3.toExpression)('null /* object */');
    }
    get isNullable() {
        return true;
    }
    get convertObjectMethod() {
        var _a;
        return `${(_a = this.schema.language.csharp) === null || _a === void 0 ? void 0 : _a.fullname}TypeConverter.ConvertFrom`;
    }
    deserializeFromContainerMember(mediaType, container, serializedName, defaultValue) {
        var _a;
        switch (mediaType) {
            case codemodel_v3_1.KnownMediaType.Json: {
                // JsonObject
                const tmp = `__${(0, codegen_1.camelCase)(['json', ...(0, codegen_1.deconstruct)(serializedName)])}`;
                return (0, codegen_csharp_3.toExpression)(`If( ${(0, codegen_csharp_3.valueOf)(container)}?.PropertyT<${clientruntime_1.ClientRuntime.JsonObject}>("${serializedName}"), out var ${tmp}) ? ${this.classDeclaration}.FromJson(${tmp}) : ${defaultValue}`);
            }
            case codemodel_v3_1.KnownMediaType.Xml: {
                // XElement/XElement or XElement/XAttribute
                const tmp = `__${(0, codegen_1.camelCase)(['xml', ...(0, codegen_1.deconstruct)(serializedName)])}`;
                // prefer specified XML name if available
                return (0, codegen_csharp_3.toExpression)(`If( ${(0, codegen_csharp_3.valueOf)(container)}?.Element("${((_a = this.schema.serialization) === null || _a === void 0 ? void 0 : _a.xml) ? this.schema.serialization.xml.name || serializedName : serializedName}"), out var ${tmp}) ? ${this.classDeclaration}.FromXml(${tmp}) : ${defaultValue}`);
            }
        }
        return (0, codegen_csharp_3.toExpression)(`${defaultValue} /* deserializeFromContainerMember doesn't support '${mediaType}' ${__filename} */`);
    }
    /** emits an expression to deserialze a container as the value itself. */
    deserializeFromNode(mediaType, node, defaultValue) {
        try {
            const tmp = (0, primitive_1.pushTempVar)();
            switch (mediaType) {
                case codemodel_v3_1.KnownMediaType.Json: {
                    // we're always going to go thru FromJson; it'll handle nulls and polymorphism.
                    return (0, codegen_csharp_3.toExpression)(`${this.classDeclaration}.FromJson(${node}) `);
                }
                case codemodel_v3_1.KnownMediaType.Xml: {
                    return (0, codegen_csharp_3.toExpression)(`If( ${(0, codegen_csharp_3.valueOf)(node)}, out var ${tmp}) ? ${this.classDeclaration}.FromXml(${tmp}) : ${defaultValue}`);
                }
            }
        }
        finally {
            (0, primitive_1.popTempVar)();
        }
        return (0, codegen_csharp_3.toExpression)(`null /* deserializeFromNode doesn't support '${mediaType}' ${__filename}*/`);
    }
    /** emits an expression serialize this to a HttpContent */
    serializeToNode(mediaType, value, serializedName, mode) {
        switch (mediaType) {
            case codemodel_v3_1.KnownMediaType.Json: {
                return (0, codegen_csharp_3.toExpression)(`${value}?.ToJson(null, ${mode.value})`);
            }
            case codemodel_v3_1.KnownMediaType.Xml: {
                return (0, codegen_csharp_3.toExpression)(`${value}?.ToXml(null, ${mode.value})`);
            }
        }
        return (0, codegen_csharp_3.toExpression)(`null /* serializeToNode doesn't support '${mediaType}' ${__filename}*/`);
    }
    /** emits an expression serialize this to the value required by the container */
    serializeToContent(mediaType, value, mode) {
        switch (mediaType) {
            case codemodel_v3_1.KnownMediaType.Json: {
                return codegen_csharp_2.System.Net.Http.StringContent.new((0, codegen_csharp_4.Ternery)((0, codegen_csharp_1.IsNotNull)(value), `${value}.ToJson(null, ${mode}).ToString()`, new codegen_csharp_3.StringExpression('{}')), codegen_csharp_2.System.Text.Encoding.UTF8);
            }
            case codemodel_v3_1.KnownMediaType.Xml: {
                return codegen_csharp_2.System.Net.Http.StringContent.new((0, codegen_csharp_4.Ternery)((0, codegen_csharp_1.IsNotNull)(value), `${value}.ToXml(null).ToString()`, codegen_csharp_2.System.String.Empty), codegen_csharp_2.System.Text.Encoding.UTF8);
            }
            //skip-for-time-being
            //       case KnownMediaType.Multipart: {
            //         let contents = '';
            //         for (const p of values(this.schema.properties)) {
            //           // to do -- add in a potential support for the filename too.
            //           contents = `${contents}${EOL}    bodyContent.Add( ${System.Net.Http.StreamContent.new(`${value}.${p.details.csharp.name}`)},"${p.serializedName}");`;
            //         }
            //         // bodyContent.Add(new _ystem.Net.Http.StreamContent(body.AudioFile), "audioFile");
            //         return toExpression(`new ${System.Func(System.Net.Http.MultipartFormDataContent)}(() =>
            // {
            //     var bodyContent = ${System.Net.Http.MultipartFormDataContent.new()};
            //     ${contents}
            //     return bodyContent;
            // })()`);
            //       }
        }
        return (0, codegen_csharp_3.toExpression)(`null /* serializeToContent doesn't support '${mediaType}' ${__filename}*/`);
    }
    /** emits an expression to deserialize content from a string */
    deserializeFromString(mediaType, content, defaultValue) {
        switch (mediaType) {
            case codemodel_v3_1.KnownMediaType.Json: {
                return this.deserializeFromNode(mediaType, clientruntime_1.ClientRuntime.JsonNode.Parse(content), defaultValue);
            }
            case codemodel_v3_1.KnownMediaType.Xml: {
                return this.deserializeFromNode(mediaType, `${codegen_csharp_2.System.Xml.Linq.XElement}.Parse(${content})`, defaultValue);
            }
        }
        return undefined;
    }
    /** emits an expression to deserialize content from a content/response */
    deserializeFromResponse(mediaType, content, defaultValue) {
        var _a;
        switch (mediaType) {
            case codemodel_v3_1.KnownMediaType.Json: {
                if ((_a = this.schema.language.csharp) === null || _a === void 0 ? void 0 : _a.hasHeaders) {
                    return (0, codegen_csharp_3.toExpression)(`${content}.Content.ReadAsStringAsync().ContinueWith( body => ${this.deserializeFromString(mediaType, 'body.Result', defaultValue)}.ReadHeaders(_response.Headers))`);
                }
                return (0, codegen_csharp_3.toExpression)(`${content}.Content.ReadAsStringAsync().ContinueWith( body => ${this.deserializeFromString(mediaType, 'body.Result', defaultValue)})`);
            }
            case codemodel_v3_1.KnownMediaType.Xml: {
                return (0, codegen_csharp_3.toExpression)(`${content}.Content.ReadAsStringAsync().ContinueWith( body => ${this.deserializeFromString(mediaType, 'body.Result', defaultValue)})`);
            }
        }
        return (0, codegen_csharp_3.toExpression)(`null /* deserializeFromResponse doesn't support '${mediaType}' ${__filename}*/`);
    }
    /** emits the code required to serialize this into a container */
    serializeToContainerMember(mediaType, value, container, serializedName, mode) {
        var _a;
        // const v = (<any>value).valuePrivate || value;
        switch (mediaType) {
            case codemodel_v3_1.KnownMediaType.Json:
                return `AddIf( null != ${value} ? (${clientruntime_1.ClientRuntime.JsonNode}) ${value}.ToJson(null,${mode.value}) : null, "${serializedName}" ,${container}.Add );`;
            case codemodel_v3_1.KnownMediaType.Xml:
                // prefer specified XML name if available
                return `AddIf( null != ${value} ? ${value}.ToXml(new ${codegen_csharp_2.System.Xml.Linq.XElement}("${((_a = this.schema.serialization) === null || _a === void 0 ? void 0 : _a.xml) ? this.schema.serialization.xml.name || serializedName : serializedName}")) : null, ${container}.Add );`;
        }
        return `/* serializeToContainerMember doesn't support '${mediaType}' ${__filename}*/`;
    }
    constructor(schema) {
        this.schema = schema;
        this.isXmlAttribute = false;
        this.isRequired = false;
    }
    validatePresence(eventListener, property) {
        return `await ${eventListener}.AssertNotNull(${(0, codegen_1.nameof)(property.value)}, ${property}); `.trim();
    }
    validateValue(eventListener, property) {
        return `await ${eventListener}.AssertObjectIsValid(${(0, codegen_1.nameof)(property.value)}, ${property}); `;
    }
    get declaration() { var _a, _b; return `${(_a = this.schema.language.csharp) === null || _a === void 0 ? void 0 : _a.namespace}.${(_b = this.schema.language.csharp) === null || _b === void 0 ? void 0 : _b.interfaceName}`; }
    get classDeclaration() { var _a, _b; return `${(_a = this.schema.language.csharp) === null || _a === void 0 ? void 0 : _a.namespace}.${(_b = this.schema.language.csharp) === null || _b === void 0 ? void 0 : _b.name}`; }
}
exports.ObjectImplementation = ObjectImplementation;
//# sourceMappingURL=object.js.map