"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildAzureSessionIdentifierForTestRun = buildAzureSessionIdentifierForTestRun;
exports.isSessionBundlePrepared = isSessionBundlePrepared;
exports.getPreparedSessionProviderFilePath = getPreparedSessionProviderFilePath;
exports.cacheSessionBundleZip = cacheSessionBundleZip;
exports.getSessionBundleZip = getSessionBundleZip;
exports.isSessionJsBootstrapWarm = isSessionJsBootstrapWarm;
exports.markSessionJsBootstrapWarm = markSessionJsBootstrapWarm;
exports.markSessionBundlePrepared = markSessionBundlePrepared;
exports.clearTestRunAzureSessionState = clearTestRunAzureSessionState;
exports.listAzureSessionCleanupTargets = listAzureSessionCleanupTargets;
exports.cleanupAzureSessionsForTestRun = cleanupAzureSessionsForTestRun;
const logger_1 = __importDefault(require("../../logger"));
const buildProviderForEval_1 = require("../customAIApplication/buildProviderForEval");
const client_1 = require("./client");
const prepareSessionBundle_1 = require("./prepareSessionBundle");
const sessionExecutionLock_1 = require("./sessionExecutionLock");
const runCustomProvider_1 = require("./runCustomProvider");
const MAX_SESSION_IDENTIFIER_LENGTH = 256;
const preparedSessionBundles = new Set();
const preparedSessionProviderPaths = new Map();
/** Zip bytes for re-upload before each invoke (Files API uploads persist; in-session extract does not). */
const sessionBundleZipBuffers = new Map();
/** Azure session already ran full JS bootstrap (extract + require); later evals use invoke-only code. */
const sessionJsBootstrapWarm = new Set();
const testRunSessionKeys = new Map();
function sanitizeSessionPart(value) {
    return value.replace(/[^a-zA-Z0-9_-]/g, '-').replace(/-+/g, '-');
}
/**
 * Stable Azure Sessions identifier for all provider calls in one functional test run.
 */
function buildAzureSessionIdentifierForTestRun(testRunId, applicationId) {
    const id = `trusys-${sanitizeSessionPart(testRunId)}-${sanitizeSessionPart(applicationId)}`;
    return id.length > MAX_SESSION_IDENTIFIER_LENGTH
        ? id.slice(0, MAX_SESSION_IDENTIFIER_LENGTH)
        : id;
}
function isSessionBundlePrepared(sessionIdentifier) {
    return preparedSessionBundles.has(sessionIdentifier);
}
function getPreparedSessionProviderFilePath(sessionIdentifier) {
    return preparedSessionProviderPaths.get(sessionIdentifier);
}
function cacheSessionBundleZip(sessionIdentifier, zipBuffer) {
    sessionBundleZipBuffers.set(sessionIdentifier, zipBuffer);
}
function getSessionBundleZip(sessionIdentifier) {
    return sessionBundleZipBuffers.get(sessionIdentifier);
}
function isSessionJsBootstrapWarm(sessionIdentifier) {
    return sessionJsBootstrapWarm.has(sessionIdentifier);
}
function markSessionJsBootstrapWarm(sessionIdentifier) {
    sessionJsBootstrapWarm.add(sessionIdentifier);
}
function markSessionBundlePrepared(testRunId, sessionIdentifier, providerFilePath) {
    preparedSessionBundles.add(sessionIdentifier);
    if (providerFilePath) {
        preparedSessionProviderPaths.set(sessionIdentifier, providerFilePath);
    }
    const keys = testRunSessionKeys.get(testRunId) ?? new Set();
    keys.add(sessionIdentifier);
    testRunSessionKeys.set(testRunId, keys);
}
function clearTestRunAzureSessionState(testRunId) {
    const keys = testRunSessionKeys.get(testRunId);
    if (keys) {
        for (const sessionKey of keys) {
            preparedSessionBundles.delete(sessionKey);
            preparedSessionProviderPaths.delete(sessionKey);
            sessionBundleZipBuffers.delete(sessionKey);
            sessionJsBootstrapWarm.delete(sessionKey);
            (0, prepareSessionBundle_1.clearSessionPrepareInFlight)(sessionKey);
            (0, sessionExecutionLock_1.clearAzureSessionExecutionLock)(sessionKey);
        }
        testRunSessionKeys.delete(testRunId);
    }
}
function listAzureSessionCleanupTargets(providers, testRunId) {
    if (!testRunId || !Array.isArray(providers)) {
        return [];
    }
    const targets = [];
    for (const provider of providers) {
        if (!provider || typeof provider !== 'object') {
            continue;
        }
        const record = provider;
        if (record.id !== buildProviderForEval_1.AZURE_SESSIONS_CUSTOM_AI_PROVIDER_ID) {
            continue;
        }
        const applicationId = record.config?.applicationId;
        const language = (0, runCustomProvider_1.normalizeAzureSessionLanguage)(record.config?.language ?? '');
        if (!applicationId || !language) {
            continue;
        }
        targets.push({
            language,
            sessionIdentifier: buildAzureSessionIdentifierForTestRun(testRunId, applicationId),
        });
    }
    return targets;
}
async function cleanupAzureSessionsForTestRun(providers, testRunId) {
    const targets = listAzureSessionCleanupTargets(providers, testRunId);
    clearTestRunAzureSessionState(testRunId);
    await Promise.allSettled(targets.map(async ({ language, sessionIdentifier }) => {
        try {
            const client = new client_1.AzureSessionsClient(language, sessionIdentifier);
            await client.deleteSession();
            logger_1.default.info(`Azure Sessions: deleted test-run session language=${language} session=${sessionIdentifier}`);
        }
        catch (error) {
            logger_1.default.warn(`Azure Sessions: failed to delete test-run session ${sessionIdentifier}: ${error instanceof Error ? error.message : String(error)}`);
        }
    }));
}
//# sourceMappingURL=testRunSession.js.map