import { decryptJson, encryptJson } from '../middleware/crypto.js';
const MAX_JOBS = 100;
const MAX_CONCURRENT = 3;
const jobs = new Map();
const jobMeta = new Map();
let activeCount = 0;
const pendingQueue = [];
function gerarId() {
    return `job_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
}
export function criarJob(owner, repo, installationId, ref, options) {
    const id = gerarId();
    jobMeta.set(id, {
        id,
        status: 'pendente',
        criadoEm: Date.now(),
        owner,
        repo,
        installationId,
        ref,
        options
    });
    if (jobMeta.size > MAX_JOBS) {
        const entries = Array.from(jobMeta.entries())
            .sort(([, a], [, b]) => a.criadoEm - b.criadoEm);
        const toRemove = entries.slice(0, entries.length - MAX_JOBS);
        for (const [key] of toRemove) {
            jobMeta.delete(key);
            jobs.delete(key);
        }
    }
    return id;
}
function reconstruirJob(id) {
    const meta = jobMeta.get(id);
    if (!meta)
        return undefined;
    const encrypted = jobs.get(id);
    let resultado;
    if (encrypted) {
        try {
            resultado = decryptJson(encrypted);
        }
        catch {
            resultado = undefined;
        }
    }
    return { ...meta, resultado };
}
export function obterJob(id) {
    return reconstruirJob(id);
}
export function listarJobs(filtro) {
    const all = Array.from(jobMeta.keys())
        .map(id => reconstruirJob(id))
        .filter((j) => j !== undefined)
        .sort((a, b) => b.criadoEm - a.criadoEm);
    if (filtro?.owner && filtro?.repo) {
        return all.filter(j => j.owner === filtro.owner && j.repo === filtro.repo);
    }
    return all;
}
export function atualizarJob(id, updates) {
    const meta = jobMeta.get(id);
    if (!meta)
        return;
    const { resultado, ...metaUpdates } = updates;
    if (resultado) {
        jobs.set(id, encryptJson(resultado));
    }
    Object.assign(meta, metaUpdates);
}
export async function executarJob(id, execFn) {
    const job = reconstruirJob(id);
    if (!job)
        return;
    if (activeCount >= MAX_CONCURRENT) {
        await new Promise(resolve => {
            pendingQueue.push(resolve);
        });
    }
    activeCount++;
    try {
        await execFn();
    }
    catch (err) {
        atualizarJob(id, {
            status: 'erro',
            finalizadoEm: Date.now(),
            erro: err instanceof Error ? err.message : String(err)
        });
    }
    finally {
        activeCount--;
        if (pendingQueue.length > 0) {
            const next = pendingQueue.shift();
            if (next)
                next();
        }
    }
}
//# sourceMappingURL=job-manager.js.map