/**
 * Base Exception Factory for ZinTrust Framework
 * Implemented as plain functions (no classes / no prototype-based constructors).
 */
import { Logger } from '../config/logger.js';
/**
 * Plain initializer for ZinTrust framework errors.
 */
export function initZintrustError(target, init = {}) {
    const mutable = target;
    if (init.name !== undefined) {
        target.name = init.name;
    }
    mutable.statusCode = init.statusCode ?? 500;
    mutable.code = init.code ?? 'INTERNAL_ERROR';
    if (init.details !== undefined) {
        mutable.details = init.details;
    }
    if (init.prototype !== undefined) {
        Object.setPrototypeOf(target, init.prototype);
    }
    if (Error?.captureStackTrace !== undefined) {
        Error.captureStackTrace(target, (init.captureStackTraceCtor ?? initZintrustError));
    }
}
function createTypedZintrustError(message, statusCode, code, name, details) {
    // Use `globalThis.Error` to avoid the project's `new Error(...)` restricted syntax selector.
    const error = new globalThis.Error(message);
    initZintrustError(error, {
        statusCode,
        code,
        details,
        name,
        prototype: Error.prototype,
        captureStackTraceCtor: createTypedZintrustError,
    });
    return error;
}
/**
 * Plain error creators.
 */
export function ZintrustError(message, details) {
    return createTypedZintrustError(message, 500, 'INTERNAL_ERROR', 'ZintrustError', details);
}
export function createDatabaseError(message, details) {
    return createTypedZintrustError(message, 500, 'DATABASE_ERROR', 'DatabaseError', details);
}
export function createWorkerError(message, details) {
    return createTypedZintrustError(message, 500, 'WORKER_ERROR', 'WorkerError', details);
}
export function createValidationError(message, details) {
    return createTypedZintrustError(message, 400, 'VALIDATION_ERROR', 'ValidationError', details);
}
export function createNotFoundError(message = 'Resource not found', details) {
    return createTypedZintrustError(message, 404, 'NOT_FOUND', 'NotFoundError', details);
}
export function createUnauthorizedError(message = 'Unauthorized', details) {
    return createTypedZintrustError(message, 401, 'UNAUTHORIZED', 'UnauthorizedError', details);
}
export function createForbiddenError(message = 'Forbidden', details) {
    return createTypedZintrustError(message, 403, 'FORBIDDEN', 'ForbiddenError', details);
}
export function createConnectionError(message, details) {
    return createTypedZintrustError(message, 500, 'CONNECTION_ERROR', 'ConnectionError', details);
}
export function createConfigError(message, details) {
    return createTypedZintrustError(message, 500, 'CONFIG_ERROR', 'ConfigError', details);
}
export function createGeneralError(message, details) {
    return createTypedZintrustError(message, 500, 'GENERAL_ERROR', 'GeneralError', details);
}
export function createCliError(message, details) {
    return createTypedZintrustError(message, 1, 'CLI_ERROR', 'CliError', details);
}
export function createSecurityError(message, details) {
    return createTypedZintrustError(message, 401, 'SECURITY_ERROR', 'SecurityError', details);
}
export function createTryCatchError(message, details) {
    Logger.error(message, details);
    return createTypedZintrustError(message, 500, 'TRY_CATCH_ERROR', 'CatchError', details);
}
/**
 * Truncate a string if it exceeds maximum length
 */
function truncateString(str, maxLen) {
    if (str.length <= maxLen)
        return str;
    return `${str.slice(0, 16)}...${str.slice(-8)}`;
}
/**
 * Redact sensitive values for error messages
 */
function redactValue(value) {
    if (value === null || value === undefined)
        return String(value);
    const MAX_LEN = 48;
    if (typeof value === 'string') {
        return truncateString(value, MAX_LEN);
    }
    if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
        return String(value);
    }
    if (typeof value === 'symbol') {
        return 'Symbol';
    }
    if (typeof value === 'function') {
        return 'Function';
    }
    // Avoid stringifying binary buffers (can leak secrets and/or blow up logs).
    if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
        return `Buffer(len=${value.length})`;
    }
    if (value instanceof Uint8Array) {
        return `Uint8Array(len=${value.length})`;
    }
    if (Array.isArray(value)) {
        return `Array(len=${value.length})`;
    }
    if (typeof value === 'object') {
        return 'Object';
    }
    return truncateString(String(value), MAX_LEN);
}
/**
 * Create a sanitizer error with method name, reason, and redacted value
 */
export function createSanitizerError(method, reason, value) {
    const redacted = redactValue(value);
    const message = `Sanitizer.${method}() failed: ${reason} (value: ${redacted})`;
    return createTypedZintrustError(message, 400, 'SANITIZER_ERROR', 'SanitizerError', {
        method,
        reason,
        redactedValue: redacted,
    });
}
/**
 * Backward compatibility Errors object.
 */
export const Errors = Object.freeze({
    database: (message, details) => createDatabaseError(message, details),
    notFound: (message, details) => createNotFoundError(message ?? 'Resource not found', details),
    validation: (message, details) => createValidationError(message, details),
    unauthorized: (message, details) => createUnauthorizedError(message ?? 'Unauthorized', details),
    forbidden: (message, details) => createForbiddenError(message ?? 'Forbidden', details),
    connection: (message, details) => createConnectionError(message, details),
    config: (message, details) => createConfigError(message, details),
    general: (message, details) => createGeneralError(message, details),
    cli: (message, details) => createCliError(message, details),
    security: (message, details) => createSecurityError(message, details),
    catchError: (message, details) => createTryCatchError(message, details),
    sanitizer: (method, reason, value) => createSanitizerError(method, reason, value),
});
/**
 * Centralized ErrorFactory for creating standardized errors.
 */
export const ErrorFactory = Object.freeze({
    createDatabaseError: (message, details) => createDatabaseError(message, details),
    createWorkerError: (message, details) => createWorkerError(message, details),
    createConnectionError: (message, details) => createConnectionError(message, details),
    createConfigError: (message, details) => createConfigError(message, details),
    createValidationError: (message, details) => createValidationError(message, details),
    createGeneralError: (message, details) => createGeneralError(message, details),
    createTryCatchError: (message, details) => createTryCatchError(message, details),
    createCliError: (message, details) => createCliError(message, details),
    createSecurityError: (message, details) => createSecurityError(message, details),
    createNotFoundError: (message, details) => createNotFoundError(message ?? 'Resource not found', details),
    createUnauthorizedError: (message, details) => createUnauthorizedError(message ?? 'Unauthorized', details),
    createSanitizerError: (method, reason, value) => createSanitizerError(method, reason, value),
    createForbiddenError: (message, details) => createForbiddenError(message ?? 'Forbidden', details),
});
