/**
 * Context Types for NeuroLink - Factory Pattern Implementation
 * Provides type-safe context integration for AI generation
 */
/**
 * Factory for context processing
 */
export class ContextFactory {
    /**
     * Default framework fields configuration
     */
    static DEFAULT_FRAMEWORK_FIELDS = {
        defaultFields: [
            "sessionId",
            "userId",
            "apiToken",
            "authToken",
            "apiEndpoint",
            "serviceUrl",
            "endpoint",
            "environment",
            "region",
            "enabledFeatures",
            "platformType",
            "platformUrl",
            "platformId",
            "enableDemoMode",
        ],
        additionalFields: [],
        includeFields: [],
    };
    /**
     * Current framework fields configuration
     */
    static frameworkFieldsConfig = ContextFactory.DEFAULT_FRAMEWORK_FIELDS;
    /**
     * Flag to track if framework fields have been initialized
     */
    static isFrameworkFieldsInitialized = false;
    /**
     * Configure framework fields for exclusion from custom data
     */
    static configureFrameworkFields(config) {
        ContextFactory.frameworkFieldsConfig = {
            ...ContextFactory.DEFAULT_FRAMEWORK_FIELDS,
            ...config,
        };
        ContextFactory.isFrameworkFieldsInitialized = true;
    }
    /**
     * Get current framework fields configuration
     * Ensures lazy initialization if not already loaded
     */
    static getFrameworkFieldsConfig() {
        // Lazy initialization - load from environment if not explicitly configured
        if (!ContextFactory.isFrameworkFieldsInitialized) {
            ContextFactory.loadFrameworkFieldsFromEnv();
            ContextFactory.isFrameworkFieldsInitialized = true;
        }
        return { ...ContextFactory.frameworkFieldsConfig };
    }
    /**
     * Reset framework fields configuration to default
     */
    static resetFrameworkFieldsConfig() {
        ContextFactory.frameworkFieldsConfig = {
            ...ContextFactory.DEFAULT_FRAMEWORK_FIELDS,
        };
    }
    /**
     * Load framework fields configuration from environment variables
     * Supports NEUROLINK_CONTEXT_EXCLUDE_FIELDS and NEUROLINK_CONTEXT_INCLUDE_FIELDS
     */
    static loadFrameworkFieldsFromEnv() {
        const excludeFields = process.env.NEUROLINK_CONTEXT_EXCLUDE_FIELDS;
        const includeFields = process.env.NEUROLINK_CONTEXT_INCLUDE_FIELDS;
        const overrideFields = process.env.NEUROLINK_CONTEXT_OVERRIDE_FIELDS;
        const config = {};
        if (excludeFields) {
            config.additionalFields = excludeFields
                .split(",")
                .map((f) => f.trim())
                .filter(Boolean);
        }
        if (includeFields) {
            config.includeFields = includeFields
                .split(",")
                .map((f) => f.trim())
                .filter(Boolean);
        }
        if (overrideFields) {
            config.overrideFields = overrideFields
                .split(",")
                .map((f) => f.trim())
                .filter(Boolean);
        }
        // Optimized check: avoid creating array with Object.keys() for simple property existence check
        const hasConfigChanges = config.additionalFields || config.includeFields || config.overrideFields;
        if (hasConfigChanges) {
            ContextFactory.configureFrameworkFields(config);
        }
        ContextFactory.isFrameworkFieldsInitialized = true;
    }
    /**
     * Add additional fields to exclude
     */
    static addFrameworkFieldsToExclude(fields) {
        const currentConfig = ContextFactory.frameworkFieldsConfig;
        ContextFactory.configureFrameworkFields({
            additionalFields: [...(currentConfig.additionalFields || []), ...fields],
        });
    }
    /**
     * Add fields to include (override exclusion)
     */
    static addFrameworkFieldsToInclude(fields) {
        const currentConfig = ContextFactory.frameworkFieldsConfig;
        ContextFactory.configureFrameworkFields({
            includeFields: [...(currentConfig.includeFields || []), ...fields],
        });
    }
    /**
     * Default context configuration
     */
    static DEFAULT_CONFIG = {
        mode: "metadata_only",
        includeInPrompt: false,
        includeInAnalytics: true,
        includeInEvaluation: true,
        maxLength: 1000,
    };
    /**
     * Validate and normalize context data
     */
    static validateContext(context) {
        if (!context || typeof context !== "object") {
            return null;
        }
        try {
            // Ensure it's JSON serializable
            const serialized = JSON.stringify(context);
            const parsed = JSON.parse(serialized);
            // Basic validation
            if (typeof parsed !== "object" || Array.isArray(parsed)) {
                return null;
            }
            return parsed;
        }
        catch {
            return null;
        }
    }
    /**
     * Process context for AI generation based on configuration
     */
    static processContext(context, config = {}) {
        const startTime = Date.now();
        const finalConfig = { ...ContextFactory.DEFAULT_CONFIG, ...config };
        let processedContext = null;
        const template = "default";
        let truncated = false;
        if (finalConfig.includeInPrompt && finalConfig.mode !== "metadata_only") {
            processedContext = ContextFactory.formatContextForPrompt(context, finalConfig);
            // Truncate if necessary
            if (finalConfig.maxLength &&
                processedContext.length > finalConfig.maxLength) {
                processedContext =
                    processedContext.substring(0, finalConfig.maxLength) + "...";
                truncated = true;
            }
        }
        const processingTime = Date.now() - startTime;
        return {
            originalContext: context,
            processedContext,
            config: finalConfig,
            metadata: {
                truncated,
                processingTime,
                template,
                mode: finalConfig.mode,
            },
        };
    }
    /**
     * Format context for prompt integration
     */
    static formatContextForPrompt(context, config) {
        switch (config.mode) {
            case "prompt_prefix":
                return ContextFactory.formatAsPrefix(context);
            case "prompt_suffix":
                return ContextFactory.formatAsSuffix(context);
            case "system_prompt":
                return ContextFactory.formatForSystemPrompt(context);
            case "structured_prompt":
                return ContextFactory.formatStructured(context);
            case "metadata_only":
            case "none":
            default:
                return "";
        }
    }
    /**
     * Format context as prompt prefix
     */
    static formatAsPrefix(context) {
        const parts = [];
        if (context.userId) {
            parts.push(`User: ${context.userId}`);
        }
        if (context.userRole) {
            parts.push(`Role: ${context.userRole}`);
        }
        if (context.sessionId) {
            parts.push(`Session: ${context.sessionId}`);
        }
        if (parts.length === 0) {
            return "";
        }
        return `Context: ${parts.join(", ")}\n\n`;
    }
    /**
     * Format context as prompt suffix
     */
    static formatAsSuffix(context) {
        const relevantKeys = Object.keys(context).filter((key) => !["userId", "sessionId", "requestId"].includes(key));
        if (relevantKeys.length === 0) {
            return "";
        }
        const contextData = relevantKeys.reduce((acc, key) => {
            acc[key] = context[key];
            return acc;
        }, {});
        return `\n\nAdditional Context: ${JSON.stringify(contextData, null, 2)}`;
    }
    /**
     * Format context for system prompt
     */
    static formatForSystemPrompt(context) {
        const parts = [];
        if (context.userRole) {
            parts.push(`You are assisting a user with the role: ${context.userRole}`);
        }
        if (context.organizationId) {
            parts.push(`Organization context: ${context.organizationId}`);
        }
        if (context.userPreferences) {
            parts.push(`User preferences: ${JSON.stringify(context.userPreferences)}`);
        }
        return parts.join(". ");
    }
    /**
     * Format context in structured format
     */
    static formatStructured(context) {
        return `[CONTEXT]\n${JSON.stringify(context, null, 2)}\n[/CONTEXT]\n\n`;
    }
    /**
     * Extract analytics data from context
     */
    static extractAnalyticsContext(context) {
        return {
            hasUserId: !!context.userId,
            hasSessionId: !!context.sessionId,
            hasUserRole: !!context.userRole,
            hasOrgContext: !!context.organizationId,
            contextKeys: Object.keys(context),
            contextSize: JSON.stringify(context).length,
        };
    }
    /**
     * Extract evaluation context
     */
    static extractEvaluationContext(context) {
        return {
            userRole: context.userRole || "unknown",
            applicationContext: context.applicationContext?.name || "unknown",
            organizationContext: context.organizationId || "unknown",
            hasPreferences: !!context.userPreferences,
        };
    }
}
/**
 * Type guard to check if value is valid context
 */
function _isValidContext(value) {
    return ContextFactory.validateContext(value) !== null;
}
export class ContextConverter {
    /**
     * Convert legacy business context to generic domain context
     * Based on business context patterns
     */
    static convertBusinessContext(legacyContext, domainType, options = {}) {
        const { preserveLegacyFields = false, validateDomainData: _validateDomainData = true, includeMetadata = true, } = options;
        return {
            sessionId: legacyContext.sessionId,
            userId: legacyContext.userId,
            config: {
                domainType,
                providerConfig: {
                    token: legacyContext.apiToken ||
                        legacyContext.authToken ||
                        legacyContext.accessToken,
                    endpoint: legacyContext.apiEndpoint || legacyContext.serviceUrl,
                    provider: ContextConverter.inferProvider(legacyContext),
                },
                platformConfig: {
                    type: legacyContext.platformType || "generic",
                    url: legacyContext.platformUrl || legacyContext.serviceUrl,
                    id: legacyContext.platformId || legacyContext.serviceId,
                    integrations: legacyContext.platformIntegrations || [],
                },
                operationalConfig: {
                    demoMode: legacyContext.enableDemoMode || false,
                    environment: legacyContext.environment || "production",
                    region: legacyContext.region,
                    features: legacyContext.enabledFeatures || [],
                },
                customData: {
                    // Preserve domain-specific fields if needed
                    ...(preserveLegacyFields
                        ? {
                            entityId: legacyContext.entityId || legacyContext.organizationId,
                            departmentId: legacyContext.departmentId,
                            projectId: legacyContext.projectId,
                        }
                        : {}),
                    // Include all additional custom data
                    ...ContextConverter.extractCustomData(legacyContext),
                },
            },
            metadata: includeMetadata
                ? {
                    convertedFrom: "legacy-business-context",
                    conversionTime: Date.now(),
                    originalKeys: Object.keys(legacyContext),
                    domainType,
                }
                : undefined,
        };
    }
    /**
     * Create execution context for required domain
     */
    static createDomainContext(domainType, domainData, sessionInfo = {}) {
        return {
            sessionId: sessionInfo.sessionId || `session_${Date.now()}`,
            userId: sessionInfo.userId,
            config: {
                domainType,
                customData: domainData,
            },
            metadata: {
                source: "domain-context-factory",
                createdAt: Date.now(),
                domainType,
            },
        };
    }
    static inferProvider(context) {
        // Generic provider inference based on context structure
        if (context.apiToken || context.authToken) {
            return "api-provider";
        }
        if (context.serviceUrl || context.endpoint) {
            return "service-provider";
        }
        return "generic-provider";
    }
    static extractCustomData(context) {
        // Get current framework fields configuration
        const config = ContextFactory.getFrameworkFieldsConfig();
        // Build the set of fields to exclude
        let fieldsToExclude;
        if (config.overrideFields) {
            // Use override fields completely
            fieldsToExclude = new Set(config.overrideFields);
        }
        else {
            // Use default fields + additional fields
            fieldsToExclude = new Set([
                ...config.defaultFields,
                ...(config.additionalFields || []),
            ]);
        }
        // Remove filtered fields that should be included despite being in the exclude list
        if (config.includeFields) {
            config.includeFields.forEach((field) => fieldsToExclude.delete(field));
        }
        const customData = {};
        Object.entries(context).forEach(([key, value]) => {
            if (!fieldsToExclude.has(key)) {
                customData[key] = value;
            }
        });
        return customData;
    }
}
//# sourceMappingURL=contextTypes.js.map