/**
 * Configuration Schema
 * Defines the structure and types for ZinTrust configuration
 */
import { Env } from '../../config/env.js';
/**
 * Default configuration values
 */
export const DEFAULT_CONFIG = Object.freeze({
    name: 'zintrust-app',
    version: '1.0.0',
    description: 'A ZinTrust application',
    author: 'Developer',
    database: {
        connection: 'sqlite',
        charset: 'utf8',
        collation: 'utf8_unicode_ci',
        synchronize: true,
        logging: false,
    },
    server: {
        port: 7777,
        host: '0.0.0.0',
        environment: 'development',
        debug: false,
        profiling: false,
        tracing: false,
    },
    auth: {
        enabled: false,
        strategy: 'jwt',
        expiresIn: '7d',
    },
    microservices: {
        enabled: false,
        port: 3001,
        discoveryType: 'filesystem',
        healthCheckInterval: 30000,
    },
    features: {
        auth: false,
        database: true,
        cache: false,
        queue: false,
        storage: false,
        email: false,
        webhooks: false,
        monitoring: false,
    },
});
/**
 * Configuration paths
 */
const HOME_DIR = Env.HOME || Env.USERPROFILE || '';
const GLOBAL_DIR = `${HOME_DIR}/.zintrust`;
/**
 * Configuration paths
 * Sealed namespace for immutability
 */
export const ConfigPaths = Object.freeze({
    GLOBAL_DIR,
    GLOBAL_CONFIG: `${GLOBAL_DIR}/config.json`,
    PROJECT_CONFIG: '.zintrust.json',
    PROJECT_CONFIG_TS: 'zintrust.config.ts',
    ENV_FILE: '.env',
    ENV_EXAMPLE: '.env.example',
});
/**
 * Validation rules for each config section
 * Sealed namespace for immutability
 */
export const CONFIG_RULES = Object.freeze({
    name: {
        type: 'string',
        required: true,
        minLength: 3,
        maxLength: 100,
        pattern: /^[a-z\d\-_]+$/i,
        description: 'Project name (alphanumeric, hyphens, underscores)',
    },
    version: {
        type: 'string',
        required: true,
        // SemVer: MAJOR.MINOR.PATCH with optional -prerelease and +build metadata
        // Avoids `.*` patterns (Sonar S5852: potential super-linear backtracking).
        pattern: /^\d+\.\d+\.\d+(?:-[\dA-Za-z.-]+)?(?:\+[\dA-Za-z.-]+)?$/,
        description: 'Semantic version (e.g. 1.0.0)',
    },
    'server.port': {
        type: 'number',
        required: true,
        min: 1024,
        max: 65535,
        description: 'Server port (1024-65535)',
    },
    'server.environment': {
        type: 'string',
        required: true,
        enum: ['development', 'production', 'testing'],
        description: 'Deployment environment',
    },
    'database.connection': {
        type: 'string',
        required: true,
        enum: ['sqlite', 'postgres', 'mysql', 'mariadb'],
        description: 'Database type',
    },
    'auth.strategy': {
        type: 'string',
        required: true,
        enum: ['jwt', 'session', 'apikey'],
        description: 'Authentication strategy',
    },
    'microservices.discoveryType': {
        type: 'string',
        required: true,
        enum: ['filesystem', 'consul', 'kubernetes'],
        description: 'Service discovery method',
    },
});
/**
 * Get default config for a specific key
 */
export function getDefaultValue(key) {
    const keys = key.split('.');
    let value = DEFAULT_CONFIG;
    for (const k of keys) {
        if (typeof value === 'object' && value !== null && k in value) {
            value = value[k];
        }
        else {
            return undefined;
        }
    }
    return value;
}
/**
 * Set config value in object (deep set)
 */
export function setConfigValue(obj, path, value) {
    const keys = path.split('.');
    let current = obj;
    for (let i = 0; i < keys.length - 1; i++) {
        const key = keys[i];
        if (!(key in current)) {
            current[key] = {};
        }
        current = current[key];
    }
    const lastKey = keys.at(-1);
    if (lastKey !== undefined) {
        current[lastKey] = value;
    }
}
/**
 * Get config value from object (deep get)
 */
export function getConfigValue(obj, path) {
    const keys = path.split('.');
    let current = obj;
    for (const key of keys) {
        if (typeof current === 'object' &&
            current !== null &&
            key in current) {
            current = current[key];
        }
        else {
            return undefined;
        }
    }
    return current;
}
