"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CustomAICliOnlyProvider = exports.AzureSessionsCustomAIProvider = exports.prepareAzureSessionsForTestRunProviders = void 0;
const types_1 = require("../util/customAIApplication/types");
const validateCustomAIBundle_1 = require("../util/customAIApplication/validateCustomAIBundle");
const azureSessions_1 = require("../util/azureSessions");
const testRunSession_1 = require("../util/azureSessions/testRunSession");
const prepareSessionBundle_1 = require("../util/azureSessions/prepareSessionBundle");
Object.defineProperty(exports, "prepareAzureSessionsForTestRunProviders", { enumerable: true, get: function () { return prepareSessionBundle_1.prepareAzureSessionsForTestRunProviders; } });
const logger_1 = __importDefault(require("../logger"));
const SecretProviderService_1 = require("../util/secrets/SecretProviderService");
const http_1 = require("./http");
function mapLanguageToAzure(language) {
    if (language === 'python') {
        return 'py';
    }
    if (language === 'js') {
        return 'js';
    }
    return null;
}
function normalizeProviderPathInZip(applicationPath) {
    return (0, validateCustomAIBundle_1.normalizeZipEntryPath)(applicationPath.replace(/\\/g, '/'));
}
async function loadEnvFromVault(applicationId, configEnv) {
    const merged = { ...(configEnv ?? {}) };
    try {
        const secretProvider = new SecretProviderService_1.SecretProviderService({
            cloudProvider: process.env.CLOUD_PROVIDER ?? 'azure',
            vault: process.env.DEFAULT_AZURE_VAULT,
            region: process.env.AWS_REGION ?? process.env.DEFAULT_AZURE_REGION,
        });
        const vaultName = (0, types_1.getCustomAIApplicationSecretsVaultName)(applicationId);
        const exists = await secretProvider.exist(vaultName);
        if (exists) {
            const secrets = await secretProvider.getAll(vaultName);
            Object.assign(merged, secrets);
        }
    }
    catch (error) {
        logger_1.default.warn(`Failed to load custom AI env from vault: ${error}`);
    }
    return merged;
}
class AzureSessionsCustomAIProvider {
    constructor(options) {
        this.config = (options?.config ?? {});
        this.label = options?.label;
    }
    id() {
        return 'azure-sessions-custom-ai';
    }
    async callApi(prompt, context, _options) {
        if (!(0, azureSessions_1.isAzureSessionsConfigured)()) {
            return {
                error: 'Azure Sessions is not configured. Upload-mode Custom AI applications require AZURE_SESSIONS_* server configuration.',
            };
        }
        const applicationId = this.config.applicationId;
        const bundleBlobUrl = this.config.bundleBlobUrl;
        const applicationPath = this.config.applicationPath;
        const language = this.config.language;
        if (!applicationId || !bundleBlobUrl || !applicationPath || !language) {
            return { error: 'Custom AI provider is missing applicationId, bundleBlobUrl, applicationPath, or language' };
        }
        const azureLanguage = mapLanguageToAzure(language);
        if (!azureLanguage) {
            return { error: `Language "${language}" is not supported for Azure Sessions execution` };
        }
        const accessToken = this.config.trusysAccessToken;
        const apiKey = this.config.trusysApiKey;
        if (!accessToken && !apiKey) {
            return { error: 'Missing access token or API key for secure bundle download' };
        }
        const testRunId = this.config.testRunId?.trim();
        const reuseTestRunSession = Boolean(testRunId && applicationId);
        const sessionIdentifier = reuseTestRunSession
            ? (0, azureSessions_1.buildAzureSessionIdentifierForTestRun)(testRunId, applicationId)
            : undefined;
        try {
            const azureLang = (0, azureSessions_1.normalizeAzureSessionLanguage)(azureLanguage);
            if (!azureLang) {
                return { error: 'Invalid Azure Sessions language mapping' };
            }
            let providerFilePath = normalizeProviderPathInZip(applicationPath);
            let bundleZipBuffer;
            if (reuseTestRunSession && testRunId && sessionIdentifier) {
                const cachedZip = (0, testRunSession_1.getSessionBundleZip)(sessionIdentifier);
                if (cachedZip) {
                    providerFilePath =
                        (0, testRunSession_1.getPreparedSessionProviderFilePath)(sessionIdentifier) ?? providerFilePath;
                    bundleZipBuffer = cachedZip;
                }
                else {
                    providerFilePath = await (0, prepareSessionBundle_1.ensureAzureSessionBundlePrepared)({
                        accessToken,
                        apiKey,
                        testRunId,
                        applicationId,
                        bundleBlobUrl,
                        applicationPath,
                        language,
                    });
                    bundleZipBuffer =
                        (0, testRunSession_1.getSessionBundleZip)(sessionIdentifier) ??
                            (await (0, prepareSessionBundle_1.downloadCustomAIBundleZip)(bundleBlobUrl, accessToken, apiKey));
                }
            }
            else {
                bundleZipBuffer = await (0, prepareSessionBundle_1.downloadCustomAIBundleZip)(bundleBlobUrl, accessToken, apiKey);
            }
            const env = await loadEnvFromVault(applicationId);
            const result = await (0, azureSessions_1.runCustomProviderInAzureSession)({
                language: azureLang,
                prompt,
                env,
                bundleDirectory: '',
                bundleZipBuffer,
                providerFilePath,
                sessionIdentifier,
                context: { vars: context?.vars ?? {} },
                cleanupSession: !reuseTestRunSession,
            });
            if (result.providerResponse.error) {
                return { error: result.providerResponse.error };
            }
            const rawOutput = result.providerResponse.output;
            const text = typeof rawOutput === 'string'
                ? rawOutput
                : rawOutput === undefined
                    ? ''
                    : JSON.stringify(rawOutput);
            let json = rawOutput;
            if (typeof rawOutput === 'string') {
                try {
                    json = JSON.parse(rawOutput);
                }
                catch {
                    // keep as string
                }
            }
            // Custom AI applications support the same transformResponse as HTTP/WebSocket custom providers.
            // Apply it here so evaluations see provider-normalized output.
            const transform = await (0, http_1.createTransformResponse)(this.config.transformResponse);
            const transformed = transform(json, text);
            return {
                ...result.providerResponse,
                ...transformed,
                raw: rawOutput,
                providerTransformedOutput: transformed.output,
            };
        }
        catch (error) {
            return {
                error: error instanceof Error ? error.message : String(error),
            };
        }
    }
}
exports.AzureSessionsCustomAIProvider = AzureSessionsCustomAIProvider;
class CustomAICliOnlyProvider {
    constructor(options) {
        this.label = options?.label;
    }
    id() {
        return 'custom-ai-cli-only';
    }
    async callApi() {
        return {
            error: 'This Custom AI application uses Shell/CLI setup. Run evaluations with the Trusys CLI and --applicationPath, or switch to Upload Code with a validated zip bundle.',
        };
    }
}
exports.CustomAICliOnlyProvider = CustomAICliOnlyProvider;
//# sourceMappingURL=azureSessionsCustomAI.js.map