// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { NoTarget } from "@typespec/compiler";
import { InputParameterScope } from "../type/input-parameter-scope.js";
import { fromMethodParameter, fromSdkServiceMethod, getParameterDefaultValue, } from "./operation-converter.js";
import { fromSdkType } from "./type-converter.js";
import { isMultiServiceClient, isReadOnly } from "./utils.js";
export function fromSdkClients(sdkContext, clients, rootApiVersions) {
    const inputClients = [];
    for (const client of clients) {
        const inputClient = fromSdkClient(sdkContext, client, rootApiVersions);
        inputClients.push(inputClient);
    }
    return inputClients;
}
function fromSdkClient(sdkContext, client, rootApiVersions) {
    let inputClient = sdkContext.__typeCache.clients.get(client);
    if (inputClient) {
        return inputClient;
    }
    const endpointParameter = client.clientInitialization.parameters.find((p) => p.kind === "endpoint");
    const uri = getMethodUri(endpointParameter);
    // Convert all clientInitialization parameters
    const clientParameters = fromSdkClientInitializationParameters(sdkContext, client.clientInitialization.parameters, client.namespace);
    const isMultiService = isMultiServiceClient(client);
    const clientName = !client.parent && isMultiService && !client.name.toLowerCase().endsWith("client")
        ? `${client.name}Client`
        : client.name;
    inputClient = {
        kind: "client",
        name: clientName,
        namespace: client.namespace,
        doc: client.doc,
        summary: client.summary,
        methods: client.methods
            .map((m) => fromSdkServiceMethod(sdkContext, m, uri, rootApiVersions, client.namespace))
            .filter((m) => m !== undefined),
        parameters: clientParameters,
        initializedBy: client.clientInitialization.initializedBy,
        decorators: client.decorators,
        crossLanguageDefinitionId: client.crossLanguageDefinitionId,
        apiVersions: client.apiVersions,
        parent: undefined,
        children: undefined,
        isMultiServiceClient: isMultiService,
    };
    sdkContext.__typeCache.updateSdkClientReferences(client, inputClient);
    // fill parent
    if (client.parent) {
        inputClient.parent = fromSdkClient(sdkContext, client.parent, rootApiVersions);
    }
    // fill children
    if (client.children) {
        inputClient.children = client.children.map((c) => fromSdkClient(sdkContext, c, rootApiVersions));
    }
    return inputClient;
    function fromSdkClientInitializationParameters(sdkContext, parameters, namespace) {
        const inputParameters = [];
        for (const param of parameters) {
            if (param.kind === "endpoint") {
                // Convert endpoint parameters
                const endpointParams = fromSdkEndpointParameter(param);
                inputParameters.push(...endpointParams);
            }
            else if (param.kind === "method") {
                // Convert method parameters
                const methodParam = fromMethodParameter(sdkContext, param, namespace);
                inputParameters.push(methodParam);
            }
            // Note: credential parameters are handled separately in service-authentication.ts
            // and are not included in the client parameters list
        }
        return inputParameters;
    }
    function fromSdkEndpointParameter(p) {
        if (p.type.kind === "union") {
            return fromSdkEndpointType(p.type.variantTypes[0]);
        }
        else {
            return fromSdkEndpointType(p.type);
        }
    }
    function fromSdkEndpointType(type) {
        // TODO: support free-style endpoint url with multiple parameters
        const endpointExpr = type.serverUrl
            .replace("https://", "")
            .replace("http://", "")
            .split("/")[0];
        if (!/^\{\w+\}$/.test(endpointExpr)) {
            sdkContext.logger.reportDiagnostic({
                code: "unsupported-endpoint-url",
                format: { endpoint: type.serverUrl },
                target: NoTarget,
            });
            return [];
        }
        const endpointVariableName = endpointExpr.substring(1, endpointExpr.length - 1);
        const parameters = [];
        for (const parameter of type.templateArguments) {
            const isEndpoint = parameter.name === endpointVariableName;
            const parameterType = isEndpoint
                ? {
                    kind: parameter.type.kind === "string" ? "string" : "url",
                    name: "endpoint",
                    crossLanguageDefinitionId: parameter.type.kind === "string" ? "TypeSpec.string" : "TypeSpec.url",
                }
                : fromSdkType(sdkContext, parameter.type); // TODO: consolidate with converter.fromSdkEndpointType
            parameters.push({
                kind: "endpoint",
                name: parameter.name,
                serializedName: parameter.serializedName,
                summary: parameter.summary,
                doc: parameter.doc,
                type: parameterType,
                isApiVersion: parameter.isApiVersionParam,
                optional: parameter.optional,
                scope: InputParameterScope.Client,
                isEndpoint: isEndpoint,
                defaultValue: getParameterDefaultValue(sdkContext, parameter.clientDefaultValue, parameterType),
                serverUrlTemplate: type.serverUrl,
                skipUrlEncoding: false,
                readOnly: isReadOnly(parameter),
                crossLanguageDefinitionId: parameter.crossLanguageDefinitionId,
            });
        }
        return parameters;
    }
}
function getMethodUri(p) {
    if (!p)
        return "";
    if (p.type.kind === "endpoint" && p.type.templateArguments.length > 0)
        return p.type.serverUrl;
    if (p.type.kind === "union" && p.type.variantTypes.length > 0)
        return p.type.variantTypes[0].serverUrl;
    return `{${p.name}}`;
}
//# sourceMappingURL=client-converter.js.map