import { ChatClient } from '../openai/chatClient.js';
import { AudioClient } from '../openai/audioClient.js';
import { LiveAudioTranscriptionSession } from '../openai/liveAudioTranscriptionClient.js';
import { ResponsesClient } from '../openai/responsesClient.js';
/**
 * Represents a specific variant of a model (e.g., a specific quantization or format).
 * Contains the low-level implementation for interacting with the model.
 * @internal
 */
export class ModelVariant {
    _modelInfo;
    coreInterop;
    modelLoadManager;
    constructor(modelInfo, coreInterop, modelLoadManager) {
        this._modelInfo = modelInfo;
        this.coreInterop = coreInterop;
        this.modelLoadManager = modelLoadManager;
    }
    /**
     * Gets the unique identifier of the model variant.
     * @returns The model ID.
     */
    get id() {
        return this._modelInfo.id;
    }
    /**
     * Gets the alias of the model.
     * @returns The model alias.
     */
    get alias() {
        return this._modelInfo.alias;
    }
    /**
     * Gets the detailed information about the model variant.
     * @returns The ModelInfo object.
     */
    get info() {
        return this._modelInfo;
    }
    /**
     * A ModelVariant is a single variant, so variants returns itself.
     */
    get variants() {
        return [this];
    }
    /**
     * SelectVariant is not supported on a ModelVariant.
     * Call Catalog.getModel() to get an IModel with all variants available.
     * @throws Error always.
     */
    selectVariant(_variant) {
        throw new Error(`selectVariant is not supported on a ModelVariant. ` +
            `Call Catalog.getModel("${this.alias}") to get an IModel with all variants available.`);
    }
    get contextLength() {
        return this._modelInfo.contextLength ?? null;
    }
    get inputModalities() {
        return this._modelInfo.inputModalities ?? null;
    }
    get outputModalities() {
        return this._modelInfo.outputModalities ?? null;
    }
    get capabilities() {
        return this._modelInfo.capabilities ?? null;
    }
    get supportsToolCalling() {
        return this._modelInfo.supportsToolCalling ?? null;
    }
    /**
     * Checks if the model variant is cached locally.
     * @returns True if cached, false otherwise.
     */
    get isCached() {
        const cachedModels = JSON.parse(this.coreInterop.executeCommand("get_cached_models"));
        return cachedModels.includes(this._modelInfo.id);
    }
    /**
     * Checks if the model variant is loaded in memory.
     * @returns True if loaded, false otherwise.
     */
    async isLoaded() {
        const loadedModels = await this.modelLoadManager.listLoaded();
        return loadedModels.includes(this._modelInfo.id);
    }
    /**
     * Downloads the model variant.
     * @param progressCallback - Optional callback to report download progress (0-100).
     */
    async download(progressCallback) {
        const request = { Params: { Model: this._modelInfo.id } };
        if (!progressCallback) {
            this.coreInterop.executeCommand("download_model", request);
        }
        else {
            await this.coreInterop.executeCommandStreaming("download_model", request, (chunk) => {
                const progress = parseFloat(chunk);
                if (!isNaN(progress)) {
                    progressCallback(progress);
                }
            });
        }
    }
    /**
     * Gets the local file path of the model variant.
     * @returns The local file path.
     */
    get path() {
        const request = { Params: { Model: this._modelInfo.id } };
        return this.coreInterop.executeCommand("get_model_path", request);
    }
    /**
     * Loads the model variant into memory.
     * @returns A promise that resolves when the model is loaded.
     */
    async load() {
        await this.modelLoadManager.load(this._modelInfo.id);
    }
    /**
     * Removes the model variant from the local cache.
     */
    removeFromCache() {
        this.coreInterop.executeCommand("remove_cached_model", { Params: { Model: this._modelInfo.id } });
    }
    /**
     * Unloads the model variant from memory.
     * @returns A promise that resolves when the model is unloaded.
     */
    async unload() {
        await this.modelLoadManager.unload(this._modelInfo.id);
    }
    /**
     * Creates a ChatClient for interacting with the model via chat completions.
     * @returns A ChatClient instance.
     */
    createChatClient() {
        return new ChatClient(this._modelInfo.id, this.coreInterop);
    }
    /**
     * Creates an AudioClient for interacting with the model via audio operations.
     * @returns An AudioClient instance.
     */
    createAudioClient() {
        return new AudioClient(this._modelInfo.id, this.coreInterop);
    }
    /**
     * Creates a LiveAudioTranscriptionSession for real-time audio streaming ASR.
     * @returns A LiveAudioTranscriptionSession instance.
     */
    createLiveTranscriptionSession() {
        return new LiveAudioTranscriptionSession(this._modelInfo.id, this.coreInterop);
    }
    /**
     * Creates a ResponsesClient for interacting with the model via the Responses API.
     * @param baseUrl - The base URL of the Foundry Local web service.
     * @returns A ResponsesClient instance.
     */
    createResponsesClient(baseUrl) {
        return new ResponsesClient(baseUrl, this._modelInfo.id);
    }
}
