"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.ApiClass = void 0;
const linq_1 = require("@azure-tools/linq");
const codegen_csharp_1 = require("@azure-tools/codegen-csharp");
const method_1 = require("../operation/method");
const codemodel_v3_1 = require("@azure-tools/codemodel-v3");
const http_operation_1 = require("../../utils/http-operation");
class ApiClass extends codegen_csharp_1.Class {
    // protected sender: Property;
    constructor(namespace, state, objectInitializer) {
        var _a, _b;
        super(namespace, ((_a = state.model.language.csharp) === null || _a === void 0 ? void 0 : _a.name) || '');
        this.state = state;
        this.apply(objectInitializer);
        // add basics
        // this.sender = this.add(new Property("Sender", ClientRuntime.ISendAsync));
        // add operations from code model
        // todo
        for (const operationGroup of state.model.operationGroups) {
            for (const operation of operationGroup.operations) {
                const responseType = (0, method_1.ResolveResponseType)(undefined, operation, state);
                const operationMethod = new method_1.OperationMethod(this, operation, false, state);
                const operationMethodWithResult = new method_1.OperationMethod(this, operation, false, state, false, true);
                this.addMethod(operationMethod);
                if (responseType) {
                    this.addMethod(operationMethodWithResult);
                }
                // Compare with m3, m4 operation has one more parameter called '$host'. We should skip it
                const parameters = (_b = operation.parameters) === null || _b === void 0 ? void 0 : _b.filter((param) => param.language.default.serializedName !== '$host');
                if ([...(0, linq_1.values)(parameters).select(each => { var _a; return ((_a = each.protocol.http) === null || _a === void 0 ? void 0 : _a.in) === codemodel_v3_1.ParameterLocation.Path; })].length > 0) {
                    // method has parameters in the path, so it could support '...ViaIdentity' 
                    const identityMethod = new method_1.OperationMethod(this, operation, true, state);
                    identityMethod.emitCall(false);
                    this.addMethod(identityMethod);
                    if (responseType) {
                        const identityMethodWithResult = new method_1.OperationMethod(this, operation, true, state, false, true);
                        this.addMethod(identityMethodWithResult);
                        identityMethodWithResult.emitCall(false, true);
                    }
                }
                if (this.state.project.supportJsonInput && (0, http_operation_1.hasValidBodyParameters)(operation)) {
                    const jsonMethod = new method_1.OperationMethod(this, operation, false, state, true);
                    jsonMethod.emitCall(false);
                    this.addMethod(jsonMethod);
                    if (responseType) {
                        const jsonMethodWithResult = new method_1.OperationMethod(this, operation, false, state, true, true);
                        this.addMethod(jsonMethodWithResult);
                        jsonMethodWithResult.emitCall(false, true);
                    }
                }
                // check if this exact method is been created before (because _call and _validate have less specific parameters than the api) 
                const cm = new method_1.CallMethod(this, operationMethod, state);
                if (!this.hasMethodWithSameDeclaration(cm)) {
                    this.addMethod(cm);
                    if (responseType) {
                        const cmWithResult = new method_1.CallMethod(this, operationMethodWithResult, state, undefined, true);
                        this.addMethod(cmWithResult);
                    }
                }
                const vm = new method_1.ValidationMethod(this, operationMethod, state);
                if (!this.hasMethodWithSameDeclaration(vm)) {
                    this.addMethod(vm);
                }
            }
        }
    }
}
exports.ApiClass = ApiClass;
//# sourceMappingURL=api-class.js.map