"use strict";
/**
 * Pack Rule Validator — schema gate before publish.
 *
 * Customer-facing safety net for the live pack editor (W3.3). Before any
 * pack version is persisted via PackVersionStore.publishVersion (W1.4),
 * validate the rule list so malformed inputs never become an active pack.
 *
 * Validation surface:
 *   - Capability class IDs must be recognised by the runtime
 *   - Governance actions must be in the supported set
 *   - Per-agent overrides must have non-empty approver + justification
 *   - Rules must not duplicate the same (capability, action) pair
 *   - Pack id / version / orgId required
 *
 * Returns a structured ValidationReport rather than throwing — the UI
 * surfaces issues inline, the customer fixes, then re-validates.
 *
 * @connexum/ai-governance  F-NEW-PRODUCT-COMPANY-PACK-CLASS (validator)
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.validatePackInput = validatePackInput;
const capability_classes_js_1 = require("./capability-classes.js");
const VALID_ACTIONS = new Set(['ALLOW', 'LOG', 'WARN', 'REQUIRE_APPROVAL', 'BLOCK']);
const VALID_ISOLATION = new Set(['none', 'sourced-only', 'strict']);
const VERSION_RE = /^v?\d+(\.\d+){0,2}(-[A-Za-z0-9.-]+)?$/;
const ID_RE = /^[a-zA-Z0-9._:-]+$/;
function validatePackInput(input) {
    const errors = [];
    const warnings = [];
    if (!input.id || typeof input.id !== 'string' || input.id.trim() === '') {
        errors.push({ severity: 'ERROR', field: 'id', code: 'MISSING', message: 'pack id is required' });
    }
    else if (!ID_RE.test(input.id)) {
        errors.push({
            severity: 'ERROR',
            field: 'id',
            code: 'INVALID_FORMAT',
            message: `pack id '${input.id}' contains invalid characters (allowed: a-z, A-Z, 0-9, ._:-)`,
        });
    }
    if (!input.version || typeof input.version !== 'string') {
        errors.push({ severity: 'ERROR', field: 'version', code: 'MISSING', message: 'pack version is required' });
    }
    else if (!VERSION_RE.test(input.version)) {
        errors.push({
            severity: 'ERROR',
            field: 'version',
            code: 'INVALID_FORMAT',
            message: `pack version '${input.version}' must be semver-ish (e.g. '1', '1.0', '1.2.3', '2.0.0-rc1')`,
        });
    }
    if (!input.orgId || typeof input.orgId !== 'string' || input.orgId.trim() === '') {
        errors.push({ severity: 'ERROR', field: 'orgId', code: 'MISSING', message: 'orgId is required' });
    }
    if (input.isolation !== undefined && typeof input.isolation === 'string' && !VALID_ISOLATION.has(input.isolation)) {
        errors.push({
            severity: 'ERROR',
            field: 'isolation',
            code: 'INVALID_ISOLATION',
            message: `isolation must be one of: ${[...VALID_ISOLATION].join(' / ')}`,
        });
    }
    // Rule list validation
    const rules = input.rules;
    if (!Array.isArray(rules)) {
        errors.push({
            severity: 'ERROR',
            field: 'rules',
            code: 'MISSING',
            message: 'rules must be an array (empty is allowed but conveys an inert pack)',
        });
        return { ok: false, errors, warnings };
    }
    if (rules.length === 0) {
        warnings.push({
            severity: 'WARN',
            field: 'rules',
            code: 'EMPTY_RULE_LIST',
            message: 'pack has zero rules — it will not gate any tool call',
        });
    }
    const seen = new Set();
    for (let i = 0; i < rules.length; i++) {
        const rule = rules[i];
        const fieldBase = `rules[${i}]`;
        if (!rule || typeof rule !== 'object') {
            errors.push({
                severity: 'ERROR',
                field: fieldBase,
                code: 'INVALID_FORMAT',
                message: 'rule must be an object',
            });
            continue;
        }
        if (typeof rule.capability !== 'string' || rule.capability === '') {
            errors.push({
                severity: 'ERROR',
                field: `${fieldBase}.capability`,
                code: 'MISSING',
                message: 'capability is required',
            });
            continue;
        }
        if (!capability_classes_js_1.ALL_CAPABILITY_CLASS_IDS.includes(rule.capability)) {
            errors.push({
                severity: 'ERROR',
                field: `${fieldBase}.capability`,
                code: 'UNKNOWN_CAPABILITY',
                message: `unknown capability '${rule.capability}'. Allowed: ${capability_classes_js_1.ALL_CAPABILITY_CLASS_IDS.join(' / ')}`,
            });
            continue;
        }
        if (typeof rule.action !== 'string' || !VALID_ACTIONS.has(rule.action)) {
            errors.push({
                severity: 'ERROR',
                field: `${fieldBase}.action`,
                code: 'UNKNOWN_ACTION',
                message: `unknown action '${rule.action}'. Allowed: ${[...VALID_ACTIONS].join(' / ')}`,
            });
            continue;
        }
        const key = `${rule.capability}::${rule.action}`;
        if (seen.has(key)) {
            errors.push({
                severity: 'ERROR',
                field: fieldBase,
                code: 'DUPLICATE_RULE',
                message: `duplicate rule (${rule.capability}, ${rule.action}) — keep one`,
            });
        }
        else {
            seen.add(key);
        }
    }
    return {
        ok: errors.length === 0,
        errors,
        warnings,
    };
}
//# sourceMappingURL=pack-rule-validator.js.map