// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { getClientNamespace, getClientOptions, getHttpOperationParameter, isHttpMetadata, shouldGenerateConvenient, shouldGenerateProtocol, } from "@azure-tools/typespec-client-generator-core";
import { getDeprecated, isErrorModel, NoTarget } from "@typespec/compiler";
import { getResourceOperation } from "@typespec/rest";
import { collectionFormatToDelimMap } from "../type/collection-format.js";
import { InputParameterScope } from "../type/input-parameter-scope.js";
import { convertLroFinalStateVia } from "../type/operation-final-state-via.js";
import { RequestLocation } from "../type/request-location.js";
import { parseHttpRequestMethod } from "../type/request-method.js";
import { ResponseLocation } from "../type/response-location.js";
import { getExternalDocs, getOperationId } from "./decorators.js";
import { fromSdkHttpExamples } from "./example-converter.js";
import { fromSdkType } from "./type-converter.js";
import { getClientNamespaceString, isReadOnly } from "./utils.js";
export function fromSdkServiceMethod(sdkContext, sdkMethod, uri, rootApiVersions, namespace) {
    let method = sdkContext.__typeCache.methods.get(sdkMethod);
    if (method) {
        return method;
    }
    const methodKind = sdkMethod.kind;
    switch (methodKind) {
        case "basic":
            method = createServiceMethod(sdkContext, sdkMethod, uri, rootApiVersions, namespace);
            break;
        case "paging":
            const pagingServiceMethod = createServiceMethod(sdkContext, sdkMethod, uri, rootApiVersions, namespace);
            pagingServiceMethod.pagingMetadata = loadPagingServiceMetadata(sdkContext, sdkMethod, rootApiVersions, uri, namespace);
            method = pagingServiceMethod;
            break;
        case "lro":
            const lroServiceMethod = createServiceMethod(sdkContext, sdkMethod, uri, rootApiVersions, namespace);
            lroServiceMethod.lroMetadata = loadLongRunningMetadata(sdkContext, sdkMethod);
            method = lroServiceMethod;
            break;
        case "lropaging":
            const lroPagingMethod = createServiceMethod(sdkContext, sdkMethod, uri, rootApiVersions, namespace);
            lroPagingMethod.lroMetadata = loadLongRunningMetadata(sdkContext, sdkMethod);
            lroPagingMethod.pagingMetadata = loadPagingServiceMetadata(sdkContext, sdkMethod, rootApiVersions, uri, namespace);
            method = lroPagingMethod;
            break;
        default:
            sdkContext.logger.reportDiagnostic({
                code: "unsupported-service-method",
                format: { methodKind: methodKind },
                target: NoTarget,
            });
            method = undefined;
            break;
    }
    if (method) {
        sdkContext.__typeCache.updateSdkMethodReferences(sdkMethod, method);
    }
    return method;
}
export function fromSdkServiceMethodOperation(sdkContext, method, uri, rootApiVersions) {
    let operation = sdkContext.__typeCache.operations.get(method.operation);
    if (operation) {
        return operation;
    }
    let generateConvenience = shouldGenerateConvenient(sdkContext, method.operation.__raw.operation);
    if (method.operation.verb === "patch" && generateConvenience) {
        sdkContext.logger.reportDiagnostic({
            code: "unsupported-patch-convenience-method",
            format: {
                methodCrossLanguageDefinitionId: method.crossLanguageDefinitionId,
            },
            target: method.__raw ?? NoTarget,
        });
        generateConvenience = false;
    }
    operation = {
        name: method.name,
        resourceName: getResourceOperation(sdkContext.program, method.operation.__raw.operation)?.resourceType
            .name ??
            getOperationGroupName(sdkContext, method.operation, getClientNamespaceString(sdkContext)),
        deprecated: getDeprecated(sdkContext.program, method.__raw),
        summary: method.summary,
        doc: method.doc,
        accessibility: method.access,
        parameters: fromSdkOperationParameters(sdkContext, method.operation, rootApiVersions),
        responses: fromSdkHttpOperationResponses(sdkContext, method.operation.responses),
        httpMethod: parseHttpRequestMethod(method.operation.verb),
        uri: uri,
        path: method.operation.path,
        externalDocsUrl: getExternalDocs(sdkContext, method.operation.__raw.operation)?.url,
        requestMediaTypes: getRequestMediaTypes(method.operation),
        bufferResponse: true,
        generateProtocolMethod: shouldGenerateProtocol(sdkContext, method.operation.__raw.operation),
        generateConvenienceMethod: generateConvenience,
        crossLanguageDefinitionId: method.crossLanguageDefinitionId,
        decorators: method.decorators,
        examples: method.operation.examples
            ? fromSdkHttpExamples(sdkContext, method.operation.examples)
            : undefined,
        namespace: method.__raw?.namespace
            ? getClientNamespace(sdkContext, method.__raw.namespace)
            : undefined,
    };
    sdkContext.__typeCache.updateSdkOperationReferences(method.operation, operation);
    return operation;
}
export function getParameterDefaultValue(sdkContext, clientDefaultValue, parameterType) {
    if (clientDefaultValue === undefined ||
        // a constant parameter should overwrite client default value
        parameterType.kind === "constant") {
        return undefined;
    }
    const kind = getValueType(sdkContext, clientDefaultValue);
    return {
        type: {
            kind: kind,
            name: kind,
            crossLanguageDefinitionId: `TypeSpec.${kind}`,
        },
        value: clientDefaultValue,
    };
}
function createServiceMethod(sdkContext, method, uri, rootApiVersions, namespace) {
    return {
        kind: method.kind,
        name: method.name,
        accessibility: method.access,
        apiVersions: method.apiVersions,
        doc: method.doc,
        summary: method.summary,
        operation: fromSdkServiceMethodOperation(sdkContext, method, uri, rootApiVersions),
        parameters: fromSdkServiceMethodParameters(sdkContext, method, rootApiVersions, namespace),
        response: fromSdkServiceMethodResponse(sdkContext, method.response),
        exception: method.exception
            ? fromSdkServiceMethodResponse(sdkContext, method.exception)
            : undefined,
        isOverride: method.isOverride,
        generateConvenient: method.generateConvenient,
        generateProtocol: method.generateProtocol,
        crossLanguageDefinitionId: method.crossLanguageDefinitionId,
    };
}
function getValueType(sdkContext, value) {
    switch (typeof value) {
        case "string":
            return "string";
        case "number":
            return "int32";
        case "boolean":
            return "boolean";
        case "bigint":
            return "int64";
        default:
            sdkContext.logger.reportDiagnostic({
                code: "unsupported-default-value-type",
                format: { valueType: typeof value },
                target: NoTarget,
            });
            return "unknown";
    }
}
function fromSdkServiceMethodParameters(sdkContext, method, rootApiVersions, namespace) {
    const parameters = [];
    for (const p of method.parameters) {
        const methodInputParameter = fromMethodParameter(sdkContext, p, namespace);
        const operationHttpParameter = getHttpOperationParameter(method, p);
        if (!operationHttpParameter) {
            parameters.push(methodInputParameter);
            continue;
        }
        // post-process the method parameter with information from the operation parameter
        updateMethodParameter(sdkContext, methodInputParameter, operationHttpParameter, rootApiVersions);
        parameters.push(methodInputParameter);
    }
    return parameters;
}
function updateMethodParameter(sdkContext, methodParameter, operationHttpParameter, rootApiVersions) {
    // for content type parameter
    if (isContentType(operationHttpParameter)) {
        methodParameter.type = fromSdkType(sdkContext, operationHttpParameter.type, operationHttpParameter);
    }
    methodParameter.serializedName = getNameInRequest(operationHttpParameter);
    methodParameter.location = getParameterLocation(operationHttpParameter);
    methodParameter.scope = getParameterScope(operationHttpParameter, methodParameter.type, rootApiVersions.length > 0);
    if (methodParameter.location === RequestLocation.Body) {
        // Convert constants to enums
        if (methodParameter.type.kind === "constant") {
            methodParameter.type = fromSdkType(sdkContext, operationHttpParameter.type, operationHttpParameter);
        }
    }
}
function fromSdkServiceMethodResponse(sdkContext, methodResponse) {
    return {
        type: getResponseType(sdkContext, methodResponse.type),
        resultSegments: methodResponse.resultSegments?.map((segment) => getResponseSegmentName(segment)),
    };
}
function fromSdkOperationParameters(sdkContext, operation, rootApiVersions) {
    const parameters = [];
    for (const p of operation.parameters) {
        if (p.kind === "cookie") {
            sdkContext.logger.reportDiagnostic({
                code: "unsupported-cookie-parameter",
                format: { parameterName: p.name, path: operation.path },
                target: NoTarget,
            });
            return parameters;
        }
        const param = fromParameter(sdkContext, p, rootApiVersions);
        if (param) {
            parameters.push(param);
        }
    }
    if (operation.bodyParam) {
        const bodyParam = fromParameter(sdkContext, operation.bodyParam, rootApiVersions);
        if (bodyParam) {
            parameters.push(bodyParam);
        }
    }
    return parameters;
}
export function fromParameter(sdkContext, p, rootApiVersions) {
    let parameter = sdkContext.__typeCache.operationParameters.get(p);
    if (parameter) {
        return parameter;
    }
    const parameterKind = p.kind;
    switch (parameterKind) {
        case "query":
            parameter = fromQueryParameter(sdkContext, p, rootApiVersions);
            break;
        case "path":
            parameter = fromPathParameter(sdkContext, p, rootApiVersions);
            break;
        case "header":
            parameter = fromHeaderParameter(sdkContext, p, rootApiVersions);
            break;
        case "body":
            parameter = fromBodyParameter(sdkContext, p, rootApiVersions);
            break;
        default:
            sdkContext.logger.reportDiagnostic({
                code: "unsupported-parameter-kind",
                format: { parameterKind },
                target: p.__raw ?? NoTarget,
            });
            parameter = undefined;
            break;
    }
    if (parameter) {
        sdkContext.__typeCache.operationParameters.set(p, parameter);
    }
    return parameter;
}
function fromQueryParameter(sdkContext, p, rootApiVersions) {
    const parameterType = fromSdkType(sdkContext, p.type, p);
    const retVar = {
        kind: "query",
        name: p.name,
        serializedName: getNameInRequest(p),
        summary: p.summary,
        doc: p.doc,
        type: parameterType,
        isApiVersion: p.isApiVersionParam,
        explode: isExploded(p),
        defaultValue: getParameterDefaultValue(sdkContext, p.clientDefaultValue, parameterType),
        arraySerializationDelimiter: getArraySerializationDelimiter(p),
        optional: p.optional,
        scope: getParameterScope(p, parameterType, rootApiVersions.length > 0),
        decorators: p.decorators,
        crossLanguageDefinitionId: p.crossLanguageDefinitionId,
        readOnly: isReadOnly(p),
        methodParameterSegments: getMethodParameterSegments(sdkContext, p),
    };
    sdkContext.__typeCache.updateSdkOperationParameterReferences(p, retVar);
    return retVar;
}
function fromPathParameter(sdkContext, p, rootApiVersions) {
    const parameterType = fromSdkType(sdkContext, p.type, p);
    const retVar = {
        kind: "path",
        name: p.name,
        serializedName: getNameInRequest(p),
        summary: p.summary,
        doc: p.doc,
        type: parameterType,
        isApiVersion: p.isApiVersionParam,
        explode: isExploded(p),
        style: p.style,
        allowReserved: p.allowReserved,
        skipUrlEncoding: p.allowReserved,
        defaultValue: getParameterDefaultValue(sdkContext, p.clientDefaultValue, parameterType),
        optional: p.optional,
        scope: getParameterScope(p, parameterType, rootApiVersions.length > 0),
        decorators: p.decorators,
        readOnly: isReadOnly(p),
        crossLanguageDefinitionId: p.crossLanguageDefinitionId,
        methodParameterSegments: getMethodParameterSegments(sdkContext, p),
    };
    sdkContext.__typeCache.updateSdkOperationParameterReferences(p, retVar);
    return retVar;
}
function fromHeaderParameter(sdkContext, p, rootApiVersions) {
    const parameterType = fromSdkType(sdkContext, p.type, p);
    const retVar = {
        kind: "header",
        name: p.name,
        serializedName: getNameInRequest(p),
        summary: p.summary,
        doc: p.doc,
        type: parameterType,
        isApiVersion: p.isApiVersionParam,
        collectionFormat: p.collectionFormat,
        arraySerializationDelimiter: getArraySerializationDelimiter(p),
        defaultValue: getParameterDefaultValue(sdkContext, p.clientDefaultValue, parameterType),
        optional: p.optional,
        isContentType: isContentType(p),
        scope: getParameterScope(p, parameterType, rootApiVersions.length > 0),
        readOnly: isReadOnly(p),
        decorators: p.decorators,
        crossLanguageDefinitionId: p.crossLanguageDefinitionId,
        methodParameterSegments: getMethodParameterSegments(sdkContext, p),
        collectionHeaderPrefix: getCollectionHeaderPrefix(sdkContext, p),
    };
    sdkContext.__typeCache.updateSdkOperationParameterReferences(p, retVar);
    return retVar;
}
function fromBodyParameter(sdkContext, p, rootApiVersions) {
    const parameterType = fromSdkType(sdkContext, p.type, p);
    const retVar = {
        kind: "body",
        name: p.name,
        serializedName: getNameInRequest(p),
        summary: p.summary,
        doc: p.doc,
        type: parameterType,
        isApiVersion: p.isApiVersionParam,
        contentTypes: p.contentTypes,
        defaultContentType: p.defaultContentType,
        optional: p.optional,
        scope: getParameterScope(p, parameterType, rootApiVersions.length > 0),
        decorators: p.decorators,
        readOnly: isReadOnly(p),
        crossLanguageDefinitionId: p.crossLanguageDefinitionId,
        methodParameterSegments: getMethodParameterSegments(sdkContext, p),
    };
    sdkContext.__typeCache.updateSdkOperationParameterReferences(p, retVar);
    return retVar;
}
export function fromMethodParameter(sdkContext, p, namespace) {
    let retVar = sdkContext.__typeCache.methodParmeters.get(p);
    if (retVar) {
        return retVar;
    }
    const parameterType = fromSdkType(sdkContext, p.type, p, namespace);
    retVar = {
        kind: "method",
        name: p.name,
        summary: p.summary,
        serializedName: p.name,
        doc: p.doc,
        type: parameterType,
        location: RequestLocation.None,
        isApiVersion: p.isApiVersionParam,
        defaultValue: getParameterDefaultValue(sdkContext, p.clientDefaultValue, parameterType),
        optional: p.optional,
        scope: InputParameterScope.Method,
        crossLanguageDefinitionId: p.crossLanguageDefinitionId,
        readOnly: isReadOnly(p),
        access: p.access,
        decorators: p.decorators,
    };
    sdkContext.__typeCache.updateSdkMethodParameterReferences(p, retVar);
    return retVar;
}
function loadLongRunningMetadata(sdkContext, method) {
    return {
        finalStateVia: convertLroFinalStateVia(method.lroMetadata.finalStateVia),
        finalResponse: {
            // in swagger, we allow delete to return some meaningful body content
            // for now, let assume we don't allow return type
            statusCodes: method.operation.verb === "delete" ? [204] : [200],
            bodyType: method.lroMetadata.finalResponse?.envelopeResult !== undefined
                ? fromSdkType(sdkContext, method.lroMetadata.finalResponse.envelopeResult)
                : undefined,
        },
        resultPath: method.lroMetadata.finalResultPath,
    };
}
function fromSdkHttpOperationResponses(sdkContext, operationResponses) {
    const responses = [];
    for (const r of operationResponses) {
        responses.push(fromSdkHttpOperationResponse(sdkContext, r));
    }
    return responses;
}
export function fromSdkHttpOperationResponse(sdkContext, sdkResponse) {
    let retVar = sdkContext.__typeCache.responses.get(sdkResponse);
    if (retVar) {
        return retVar;
    }
    const range = sdkResponse.statusCodes;
    retVar = {
        statusCodes: toStatusCodesArray(range),
        bodyType: getResponseType(sdkContext, sdkResponse.type),
        headers: fromSdkServiceResponseHeaders(sdkContext, sdkResponse.headers),
        isErrorResponse: sdkResponse.type !== undefined && isErrorModel(sdkContext.program, sdkResponse.type.__raw),
        contentTypes: sdkResponse.contentTypes,
    };
    sdkContext.__typeCache.updateSdkResponseReferences(sdkResponse, retVar);
    return retVar;
}
function fromSdkServiceResponseHeaders(sdkContext, headers) {
    return headers.map((h) => ({
        name: h.__raw.name,
        nameInResponse: h.serializedName,
        summary: h.summary,
        doc: h.doc,
        type: fromSdkType(sdkContext, h.type),
    }));
}
function toStatusCodesArray(range) {
    if (typeof range === "number")
        return [range];
    const statusCodes = [range.end - range.start + 1];
    for (let i = range.start; i <= range.end; i++) {
        statusCodes.push(i);
    }
    return statusCodes;
}
function getRequestMediaTypes(op) {
    const contentTypes = op.parameters.filter((p) => p.kind === "header" && p.serializedName.toLocaleLowerCase() === "content-type");
    if (contentTypes.length === 0)
        return undefined;
    return contentTypes.map((p) => getMediaTypes(p.type)).flat();
}
function getMediaTypes(type) {
    if (type.kind === "constant") {
        if (type.valueType.kind !== "string") {
            throw `Media type in "content-type" should be string. But get ${type.valueType.kind}.`;
        }
        return [type.value];
    }
    else if (type.kind === "union") {
        const mediaTypes = [];
        for (const unionItem of type.variantTypes) {
            if (unionItem.kind === "constant" && unionItem.valueType.kind === "string") {
                mediaTypes.push(unionItem.value);
            }
            else {
                throw `Media type in "content-type" should be string. But get ${unionItem.kind}.`;
            }
        }
        return mediaTypes;
    }
    else if (type.kind === "enum") {
        if (type.valueType.kind !== "string") {
            throw `Media type in "content-type" should be string. But get ${type.valueType.kind}.`;
        }
        return type.values.map((v) => v.value);
    }
    return [];
}
function loadPagingServiceMetadata(context, method, rootApiVersions, uri, namespace) {
    let nextLink;
    if (method.pagingMetadata.nextLinkSegments) {
        nextLink = {
            responseSegments: method.pagingMetadata.nextLinkSegments.map((segment) => getResponseSegmentName(segment)),
            responseLocation: getResponseLocation(context, method, method.pagingMetadata.nextLinkSegments[0]),
        };
        if (method.pagingMetadata.nextLinkOperation) {
            nextLink.operation = fromSdkServiceMethod(context, method.pagingMetadata.nextLinkOperation, uri, rootApiVersions, namespace);
        }
        if (method.pagingMetadata.nextLinkReInjectedParametersSegments &&
            method.pagingMetadata.nextLinkReInjectedParametersSegments.length > 0) {
            const nextLinkReInjectedParameters = [];
            for (const parameterSegments of method.pagingMetadata.nextLinkReInjectedParametersSegments) {
                if (parameterSegments?.length > 0) {
                    const lastParameterSegment = parameterSegments[parameterSegments.length - 1];
                    const operationParameter = getHttpOperationParameter(method, lastParameterSegment);
                    if (operationParameter) {
                        const parameter = fromParameter(context, operationParameter, rootApiVersions);
                        if (parameter) {
                            nextLinkReInjectedParameters.push(parameter);
                        }
                    }
                }
            }
            nextLink.reInjectedParameters = nextLinkReInjectedParameters;
        }
    }
    let continuationToken;
    if (method.pagingMetadata.continuationTokenParameterSegments &&
        method.pagingMetadata.continuationTokenResponseSegments) {
        // The last segment of the service method parameter can be used to map back to the protocol parameter
        const lastParameterSegment = method.pagingMetadata.continuationTokenParameterSegments[method.pagingMetadata.continuationTokenParameterSegments.length - 1];
        const continuationTokenParameter = fromParameter(context, getHttpOperationParameter(method, lastParameterSegment), rootApiVersions);
        if (continuationTokenParameter) {
            continuationToken = {
                parameter: continuationTokenParameter,
                responseSegments: method.pagingMetadata.continuationTokenResponseSegments.map((segment) => getResponseSegmentName(segment)),
                responseLocation: getResponseLocation(context, method, method.pagingMetadata.continuationTokenResponseSegments?.[0]),
            };
        }
    }
    let pageSizeParameterSegments;
    if (method.pagingMetadata.pageSizeParameterSegments) {
        pageSizeParameterSegments = method.pagingMetadata.pageSizeParameterSegments.map((segment) => segment.name);
    }
    return {
        itemPropertySegments: method.response.resultSegments.map((s) => getResponseSegmentName(s)),
        nextLink: nextLink,
        continuationToken: continuationToken,
        pageSizeParameterSegments: pageSizeParameterSegments,
    };
}
function getResponseSegmentName(segment) {
    if (segment.kind === "responseheader") {
        return segment.serializedName;
    }
    const serializedName = segment.serializationOptions?.json?.name ??
        segment.serializationOptions?.xml?.name ??
        segment.serializationOptions?.multipart?.name;
    return serializedName ?? segment.name;
}
function getResponseLocation(context, method, p) {
    if (p.kind === "responseheader") {
        return ResponseLocation.Header;
    }
    if (isHttpMetadata(context, p)) {
        context.logger.reportDiagnostic({
            code: "unsupported-continuation-location",
            format: {
                crossLanguageDefinitionId: method.crossLanguageDefinitionId,
            },
            target: NoTarget,
        });
        return ResponseLocation.None;
    }
    return ResponseLocation.Body;
}
// TODO: https://github.com/Azure/typespec-azure/issues/1441
function getParameterLocation(p) {
    switch (p?.kind) {
        case "path":
            return RequestLocation.Path;
        case "header":
            return RequestLocation.Header;
        case "query":
            return RequestLocation.Query;
        case "property":
        case "body":
            return RequestLocation.Body;
        default:
            return RequestLocation.None;
    }
}
function getParameterScope(p, type, hasGlobalApiVersion) {
    if (p.kind === "body") {
        /** TODO: remove this and use the spread metadata of parameter when https://github.com/Azure/typespec-azure/issues/1513 is resolved */
        if (type.kind === "model" && p.type !== p.correspondingMethodParams[0]?.type) {
            return InputParameterScope.Spread;
        }
        return InputParameterScope.Method;
    }
    return type.kind === "constant"
        ? InputParameterScope.Constant
        : p.isApiVersionParam
            ? hasGlobalApiVersion
                ? InputParameterScope.Client
                : InputParameterScope.Method
            : p.onClient
                ? InputParameterScope.Client
                : InputParameterScope.Method;
}
function getOperationGroupName(context, operation, namespace) {
    const explicitOperationId = getOperationId(context, operation.__raw.operation);
    if (explicitOperationId) {
        const ids = explicitOperationId.split("_");
        if (ids.length > 1) {
            return ids.slice(0, -2).join("_");
        }
    }
    if (operation.__raw.operation.interface) {
        return operation.__raw.operation.interface.name;
    }
    if (operation.__raw.operation.namespace) {
        return operation.__raw.operation.namespace.name;
    }
    return namespace;
}
// TODO: remove after https://github.com/Azure/typespec-azure/issues/1227 is fixed
function normalizeHeaderName(name) {
    switch (name.toLocaleLowerCase()) {
        case "accept":
            return "Accept";
        case "content-type":
            return "Content-Type";
        default:
            return name;
    }
}
function isExploded(p) {
    return (p.kind === "path" || p.kind === "query") && p.explode === true;
}
function isContentType(p) {
    return p.kind === "header" && p.serializedName.toLocaleLowerCase() === "content-type";
}
function getCollectionFormat(p) {
    return p.kind === "header" || p.kind === "query" ? p.collectionFormat : undefined;
}
function getSerializedName(p) {
    // use serializedName if available, but fallback to name
    // special case for body as the name is incorrectly set to "body" https://github.com/Azure/typespec-azure/issues/2292
    return "serializedName" in p && p.kind !== "body" ? (p.serializedName ?? p.name) : p.name;
}
function getNameInRequest(p) {
    const serializedName = getSerializedName(p);
    return p.kind === "header" ? normalizeHeaderName(serializedName) : serializedName;
}
function getArraySerializationDelimiter(p) {
    const format = getCollectionFormat(p);
    return format ? collectionFormatToDelimMap[format] : undefined;
}
export function getMethodParameterSegments(sdkContext, p) {
    // methodParameterSegments is a 2D array where each segment array represents a path to a method parameter
    // For spread body cases, there could be multiple paths, but we simplify by taking the first element
    // We need the complete segment path (e.g., ['Params', 'foo'] for accessing params.foo)
    const methodParameterSegments = p.methodParameterSegments;
    if (!methodParameterSegments || methodParameterSegments.length === 0) {
        return undefined;
    }
    // Take the first segment path (simplification - no spector scenario for multiple paths yet)
    const firstSegmentPath = methodParameterSegments[0];
    if (!firstSegmentPath || firstSegmentPath.length === 0) {
        return undefined;
    }
    const namespace = getClientNamespaceString(sdkContext) ?? "";
    const methodParams = [];
    // Convert each element in the segment path to an InputMethodParameter
    // This preserves the full path information (e.g., ['Params', 'foo'])
    for (const segment of firstSegmentPath) {
        const methodParam = segment;
        methodParams.push(fromMethodParameter(sdkContext, methodParam, namespace));
    }
    return methodParams.length > 0 ? methodParams : undefined;
}
function getResponseType(sdkContext, type) {
    if (!type) {
        return undefined;
    }
    // handle anonymous union enum response types by defaulting to the enum value type in the case of
    if (type.kind === "enum" && type.isUnionAsEnum && type.isGeneratedName) {
        return fromSdkType(sdkContext, type.valueType);
    }
    return fromSdkType(sdkContext, type);
}
function getCollectionHeaderPrefix(sdkContext, p) {
    const value = getClientOptions(p, "collectionHeaderPrefix");
    if (value === undefined) {
        return undefined;
    }
    // Only apply to dictionary types (unwrap nullable)
    const rawType = p.type.kind === "nullable" ? p.type.type : p.type;
    if (rawType.kind !== "dict") {
        return undefined;
    }
    if (typeof value !== "string") {
        sdkContext.logger.reportDiagnostic({
            code: "general-warning",
            format: {
                message: `The 'collectionHeaderPrefix' client option must be a string value, but got '${typeof value}'. The option will be ignored.`,
            },
            target: p.__raw ?? NoTarget,
        });
        return undefined;
    }
    return value;
}
//# sourceMappingURL=operation-converter.js.map