/**
 * Deprecation Tracking
 *
 * Tracks deprecated features with sunset dates and replacement guidance.
 * Provides warnings and compatibility checking.
 *
 * @packageDocumentation
 */
import { createLogger } from '../common/logger.js';
import { parseVersion, gte } from './semver.js';
const logger = createLogger({ component: 'deprecation' });
// ============================================================================
// Deprecation Registry Implementation
// ============================================================================
class DeprecationRegistryImpl {
    deprecations = new Map();
    currentVersion;
    constructor(currentVersion) {
        this.currentVersion = parseVersion(currentVersion);
    }
    register(deprecation) {
        this.deprecations.set(deprecation.feature, { ...deprecation, warned: false });
        logger.debug({ feature: deprecation.feature, deprecatedIn: deprecation.deprecatedIn }, 'Deprecation registered');
    }
    isDeprecated(feature, currentVersion) {
        const deprecation = this.deprecations.get(feature);
        if (!deprecation)
            return false;
        const version = currentVersion ? parseVersion(currentVersion) : this.currentVersion;
        const deprecatedIn = parseVersion(deprecation.deprecatedIn);
        return gte(version, deprecatedIn);
    }
    isRemoved(feature, currentVersion) {
        const deprecation = this.deprecations.get(feature);
        if (!deprecation || !deprecation.removedIn)
            return false;
        const version = currentVersion ? parseVersion(currentVersion) : this.currentVersion;
        const removedIn = parseVersion(deprecation.removedIn);
        return gte(version, removedIn);
    }
    get(feature) {
        return this.deprecations.get(feature);
    }
    getAll() {
        return Array.from(this.deprecations.values());
    }
    warn(feature) {
        const deprecation = this.deprecations.get(feature);
        if (!deprecation)
            return;
        if (deprecation.warned)
            return;
        deprecation.warned = true;
        const context = {
            feature,
            deprecatedIn: deprecation.deprecatedIn,
        };
        if (deprecation.removedIn) {
            context.removedIn = deprecation.removedIn;
        }
        if (deprecation.replacement) {
            context.replacement = deprecation.replacement;
        }
        if (deprecation.link) {
            context.link = deprecation.link;
        }
        logger.warn(context, `Deprecated: ${deprecation.message}`);
    }
    check(feature, currentVersion) {
        if (this.isRemoved(feature, currentVersion)) {
            const deprecation = this.deprecations.get(feature);
            throw new Error(`Feature '${feature}' was removed in version ${deprecation.removedIn}. ` +
                (deprecation.replacement ? `Use '${deprecation.replacement}' instead.` : ''));
        }
        if (this.isDeprecated(feature, currentVersion)) {
            this.warn(feature);
        }
    }
}
// ============================================================================
// Factory Functions
// ============================================================================
let registry = null;
export function createDeprecationRegistry(currentVersion) {
    registry = new DeprecationRegistryImpl(currentVersion);
    return registry;
}
export function getDeprecationRegistry() {
    if (!registry) {
        throw new Error('DeprecationRegistry not initialized');
    }
    return registry;
}
// ============================================================================
// Decorator for Deprecated Functions
// ============================================================================
/**
 * Decorator to mark a function as deprecated
 */
export function deprecated(options) {
    return function (target, propertyKey, descriptor) {
        const originalMethod = descriptor.value;
        let warned = false;
        descriptor.value = function (...args) {
            if (!warned) {
                warned = true;
                logger.warn({
                    method: String(propertyKey),
                    since: options.since,
                    until: options.until,
                    replacement: options.replacement,
                }, `Deprecated: ${options.message}`);
            }
            return originalMethod.apply(this, args);
        };
        return descriptor;
    };
}
// ============================================================================
// Pre-defined Deprecations
// ============================================================================
export const VORION_DEPRECATIONS = [
    // API Deprecations
    {
        feature: 'api.v1.legacy_aci_format',
        deprecatedIn: '1.0.0',
        removedIn: '2.0.0',
        replacement: 'Standard CAR format (a3i.org.class:domains-level@version)',
        message: 'Legacy CAR format with embedded trust tier is deprecated',
        link: 'https://docs.vorion.dev/car#migration',
    },
    {
        feature: 'api.v1.trust_score_in_response',
        deprecatedIn: '1.1.0',
        replacement: 'GET /v1/agents/{carId}/trust',
        message: 'Trust score in agent response is deprecated; use dedicated endpoint',
    },
    // SDK Deprecations
    {
        feature: 'sdk.getTrustLevel',
        deprecatedIn: '1.0.0',
        removedIn: '2.0.0',
        replacement: 'getTrustScore()',
        message: 'getTrustLevel() is deprecated; use getTrustScore() for numeric scores',
    },
    // Protocol Deprecations
    {
        feature: 'a2a.v0.message_format',
        deprecatedIn: '1.0.0',
        removedIn: '1.5.0',
        replacement: 'A2A v1.0 message format',
        message: 'A2A v0 message format is deprecated',
    },
];
/**
 * Initialize deprecation registry with pre-defined deprecations
 */
export function initDeprecations(currentVersion) {
    const reg = createDeprecationRegistry(currentVersion);
    for (const deprecation of VORION_DEPRECATIONS) {
        reg.register(deprecation);
    }
    return reg;
}
// ============================================================================
// Compatibility Helpers
// ============================================================================
/**
 * Check API version compatibility
 */
export function checkApiCompatibility(clientVersion, serverVersion, deprecations) {
    const warnings = [];
    const errors = [];
    const client = parseVersion(clientVersion);
    const server = parseVersion(serverVersion);
    // Major version mismatch = incompatible
    if (client.major !== server.major) {
        errors.push(`Major version mismatch: client ${clientVersion}, server ${serverVersion}`);
        return { compatible: false, warnings, errors };
    }
    // Client newer than server = potential issues
    if (client.minor > server.minor) {
        warnings.push(`Client version ${clientVersion} may use features not available on server ${serverVersion}`);
    }
    // Check for deprecated features
    const allDeprecations = deprecations.getAll();
    for (const dep of allDeprecations) {
        if (deprecations.isDeprecated(dep.feature, clientVersion)) {
            if (deprecations.isRemoved(dep.feature, serverVersion)) {
                errors.push(`Feature '${dep.feature}' used by client was removed in server version`);
            }
            else {
                warnings.push(`Feature '${dep.feature}' is deprecated: ${dep.message}`);
            }
        }
    }
    return { compatible: errors.length === 0, warnings, errors };
}
//# sourceMappingURL=deprecation.js.map