/**
 * SafeLogger - Secure logging utility for Local Deep Research
 *
 * This module provides secure console logging that automatically redacts
 * sensitive data in production environments to prevent information leakage
 * through client-side logs.
 *
 * SECURITY MODEL:
 * - Development Mode (localhost, 127.0.0.1, .local TLD, file: protocol):
 *   Full logging with all dynamic data visible for debugging
 *
 * - Production Mode (everything else - safe default):
 *   Only static message strings are logged; all dynamic data is redacted
 *   This protects user search queries, API responses, tokens, and other
 *   potentially sensitive information from being exposed in logs.
 *
 * Usage:
 *   SafeLogger.log('User searched:', query);
 *   SafeLogger.error('API request failed:', error);
 *   SafeLogger.warn('Connection unstable:', details);
 *
 * In development: [LOG] User searched: climate change research
 * In production:  [LOG] User searched: [redacted]
 */

(function() {
    'use strict';

    const REDACTED = '[redacted]';

    /**
     * Detect if running in production mode
     * Production is assumed for any environment that doesn't match
     * known development indicators. We use a strict allowlist to avoid
     * accidentally treating production as development.
     *
     * @returns {boolean} True if in production mode
     */
    function isProductionEnvironment() {
        const hostname = window.location.hostname.toLowerCase();

        // Only explicit localhost indicators are development
        if (hostname === 'localhost' || hostname === '127.0.0.1') {
            return false;
        }

        // .local TLD is reserved for local network (mDNS/Bonjour)
        if (hostname.endsWith('.local')) {
            return false;
        }

        // File protocol is local development
        if (window.location.protocol === 'file:') {
            return false;
        }

        // Everything else: assume production (safe default)
        // This includes non-standard ports, staging servers, etc.
        return true;
    }

    // Cache production state for performance
    let _isProduction = null;
    let _forceProductionMode = null;

    /**
     * Check if we're in production mode (with caching)
     * @returns {boolean} True if in production mode
     */
    function isProduction() {
        // Allow forcing mode for testing
        if (_forceProductionMode !== null) {
            return _forceProductionMode;
        }

        // Cache the result since it won't change during page lifecycle
        if (_isProduction === null) {
            _isProduction = isProductionEnvironment();
        }

        return _isProduction;
    }

    /**
     * Sanitize a value for logging
     * In development mode, values pass through unchanged.
     * In production mode, all dynamic data is redacted.
     *
     * @param {any} value - The value to sanitize
     * @param {boolean} isFirstArg - Whether this is the first argument (static message)
     * @returns {any} The sanitized value
     */
    function sanitize(value, isFirstArg) {
        // First argument is typically the static message - always pass through
        if (isFirstArg && typeof value === 'string') {
            return value;
        }

        // In development, show everything
        if (!isProduction()) {
            if (value instanceof Error) {
                return {
                    name: value.name,
                    message: value.message,
                    stack: value.stack
                };
            }
            // Extract .message from error-like objects (e.g., Response, custom errors)
            // so catch blocks logging raw error objects show useful text
            if (value && typeof value === 'object' && typeof value.message === 'string') {
                return value.message;
            }
            // For other objects (e.g. {error: "not found"}), stringify to avoid
            // console showing [object Object]
            if (value && typeof value === 'object') {
                try {
                    return JSON.stringify(value);
                } catch {
                    return String(value);
                }
            }
            return value;
        }

        // In production, redact all dynamic data
        if (value === null || value === undefined) {
            return value;
        }

        if (typeof value === 'boolean') {
            return value;
        }

        // Numbers could be IDs, counts, or other sensitive data
        if (typeof value === 'number') {
            return REDACTED;
        }

        // Strings contain user data, tokens, queries, etc.
        if (typeof value === 'string') {
            return REDACTED;
        }

        // For errors, keep the type but redact the message
        if (value instanceof Error) {
            return {
                name: value.name,
                message: REDACTED
            };
        }

        // Error-like objects (custom errors with the canonical {name, message}
        // shape). Both fields must be strings — checking only .message catches
        // ordinary data objects like {hasLogEntry: true, message: 'foo'} and
        // makes them look like errors in production logs.
        if (
            value &&
            typeof value === 'object' &&
            typeof value.name === 'string' &&
            typeof value.message === 'string'
        ) {
            return { name: value.name, message: REDACTED };
        }

        // Arrays - show structure but not contents
        if (Array.isArray(value)) {
            return '[Array(' + value.length + ')]';
        }

        // Objects - show type but not contents
        if (typeof value === 'object') {
            return '[Object]';
        }

        return REDACTED;
    }

    /**
     * Process log arguments for safe output
     * First argument (typically the message) passes through as-is,
     * remaining arguments are sanitized based on environment.
     *
     * @param {Array} args - The arguments passed to the log function
     * @returns {Array} The processed arguments
     */
    function processArgs(args) {
        if (args.length === 0) {
            return [];
        }

        const result = [];

        for (let i = 0; i < args.length; i++) {
            result.push(sanitize(args[i], i === 0));
        }

        return result;
    }

    /**
     * SafeLogger object with methods matching console API
     */
    const SafeLogger = {
        /**
         * Log a message (equivalent to console.log)
         * @param {...any} args - Arguments to log
         */
        log(...args) {
            // bearer:disable javascript_lang_logger_leak
            console.log(...processArgs(args));
        },

        /**
         * Log an informational message (equivalent to console.info)
         * @param {...any} args - Arguments to log
         */
        info(...args) {
            // bearer:disable javascript_lang_logger_leak
            console.info(...processArgs(args));
        },

        /**
         * Log a warning message (equivalent to console.warn)
         * @param {...any} args - Arguments to log
         */
        warn(...args) {
            // bearer:disable javascript_lang_logger_leak
            console.warn(...processArgs(args));
        },

        /**
         * Log an error message (equivalent to console.error)
         * @param {...any} args - Arguments to log
         */
        error(...args) {
            // bearer:disable javascript_lang_logger_leak
            console.error(...processArgs(args));
        },

        /**
         * Log a debug message (only in development mode)
         * In production, debug messages are completely suppressed.
         * @param {...any} args - Arguments to log
         */
        debug(...args) {
            if (!isProduction()) {
                // bearer:disable javascript_lang_logger_leak
                console.debug(...processArgs(args));
            }
        },

        /**
         * Check if running in production mode
         * @returns {boolean} True if in production mode
         */
        isProduction,

        /**
         * Force production mode on or off (for testing purposes)
         * Set to null to restore automatic detection.
         * @param {boolean|null} value - True for production, false for development, null for auto
         */
        setProductionMode(value) {
            _forceProductionMode = value;
        },

        /**
         * Get current production mode setting
         * @returns {boolean|null} Current forced mode or null if auto-detecting
         */
        getProductionMode() {
            return _forceProductionMode;
        },

        /**
         * Reset to automatic environment detection
         */
        resetProductionMode() {
            _forceProductionMode = null;
            _isProduction = null;
        }
    };

    // Export to global scope
    window.SafeLogger = SafeLogger;

    // Individual function exports for convenience
    window.safeLog = SafeLogger.log;
    window.safeLogInfo = SafeLogger.info;
    window.safeLogWarn = SafeLogger.warn;
    window.safeLogError = SafeLogger.error;
    window.safeLogDebug = SafeLogger.debug;

})();
