"use strict";
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2024-2026 Gracker (Chris)
// This file is part of SmartPerfetto. See LICENSE for details.
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mapProcessIdentityStatus = mapProcessIdentityStatus;
exports.buildIdentityResolutionFromProcessGate = buildIdentityResolutionFromProcessGate;
const crypto_1 = __importDefault(require("crypto"));
function stableHash(value) {
    return crypto_1.default
        .createHash('sha1')
        .update(JSON.stringify(value, (_key, item) => typeof item === 'bigint' ? item.toString() : item))
        .digest('hex')
        .slice(0, 12);
}
function mapProcessIdentityStatus(resolution) {
    if (!resolution)
        return 'not_required';
    if (resolution.resolverError)
        return 'error';
    if (resolution.status === 'verified')
        return 'verified';
    if (resolution.status === 'not_found')
        return 'missing';
    if (resolution.status === 'unresolved')
        return 'missing';
    const raw = String(resolution.rawStatus || '').toLowerCase();
    const warningText = resolution.warnings.join(' ').toLowerCase();
    if (raw.includes('weak') || warningText.includes('weak'))
        return 'weak';
    if (resolution.confidenceScore > 0 && resolution.confidenceScore < 50)
        return 'weak';
    return 'ambiguous';
}
function buildTarget(traceId, traceSide, target, source) {
    const timeRange = target?.startTs !== undefined && target?.endTs !== undefined
        ? { startTs: target.startTs, endTs: target.endTs }
        : undefined;
    return {
        traceId,
        traceSide: traceSide || 'current',
        packageName: target?.requestedName,
        processName: target?.requestedName,
        threadName: target?.threadName,
        upid: target?.upid,
        pid: target?.pid,
        ...(timeRange ? { timeRange } : {}),
        source,
    };
}
function processFromCandidate(candidate) {
    if (candidate.upid === undefined)
        return undefined;
    const matchSources = new Set();
    for (const sourceText of [candidate.targetMatchSources, candidate.supportingSources]) {
        if (typeof sourceText !== 'string')
            continue;
        for (const part of sourceText.split(',')) {
            const source = part.trim();
            if (source)
                matchSources.add(source);
        }
    }
    return {
        upid: candidate.upid,
        pid: candidate.pid,
        processName: candidate.processName || candidate.metadataProcessName || candidate.recommendedProcessNameParam,
        packageName: candidate.packageName || candidate.canonicalPackageName,
        matchSources: Array.from(matchSources),
        confidence: Math.max(0, Math.min(1, candidate.confidenceScore / 100)),
    };
}
function threadFromCandidate(candidate, target) {
    if (candidate.threadUtid === undefined)
        return undefined;
    if (target?.threadName && candidate.threadTargetMatched !== true)
        return undefined;
    return {
        utid: candidate.threadUtid,
        tid: candidate.threadTid,
        threadName: candidate.threadName,
        role: candidate.threadRole,
        owningUpid: candidate.upid,
        processName: candidate.processName || candidate.metadataProcessName || candidate.recommendedProcessNameParam,
        matchSources: candidate.threadName ? ['thread.name'] : [],
        confidence: Math.max(0, Math.min(1, candidate.confidenceScore / 100)),
    };
}
function buildIdentityResolutionFromProcessGate(input) {
    if (!input.target && !input.resolution)
        return undefined;
    const target = buildTarget(input.traceId, input.traceSide, input.target, input.source || 'skill_param');
    const resolution = input.resolution;
    const status = input.statusOverride || mapProcessIdentityStatus(resolution);
    const processes = (resolution?.candidates || [])
        .map(processFromCandidate)
        .filter((item) => Boolean(item));
    const threads = (resolution?.candidates || [])
        .map(candidate => threadFromCandidate(candidate, input.target))
        .filter((item) => Boolean(item));
    const warnings = [
        ...(input.warnings || []),
        ...(resolution?.warnings || []),
        ...(resolution?.resolverError ? [`resolver failed: ${resolution.resolverError}`] : []),
    ];
    const recommendedParams = {};
    if (resolution?.recommendedProcessNameParam) {
        recommendedParams.process_name = resolution.recommendedProcessNameParam;
        recommendedParams.package = resolution.recommendedProcessNameParam;
    }
    if (resolution?.upids?.length) {
        recommendedParams.upid = resolution.upids[0];
    }
    return {
        version: 'identity_contract@1',
        identityRefId: `identity:${stableHash({
            traceId: input.traceId,
            traceSide: input.traceSide || 'current',
            target,
            status,
            upids: resolution?.upids || [],
            confidence: resolution?.confidenceScore,
        })}`,
        target,
        status,
        processes,
        threads,
        warnings,
        ...(Object.keys(recommendedParams).length > 0 ? { recommendedParams } : {}),
    };
}
//# sourceMappingURL=identityContractMapper.js.map