import { LogLevel } from '@powersync/common';
/**
 * Broadcasts logs to all clients
 */
export class BroadcastLogger {
    clients;
    TRACE;
    DEBUG;
    INFO;
    TIME;
    WARN;
    ERROR;
    OFF;
    currentLevel = LogLevel.INFO;
    constructor(clients) {
        this.clients = clients;
        this.TRACE = LogLevel.TRACE;
        this.DEBUG = LogLevel.DEBUG;
        this.INFO = LogLevel.INFO;
        this.TIME = LogLevel.TIME;
        this.WARN = LogLevel.WARN;
        this.ERROR = LogLevel.ERROR;
        this.OFF = LogLevel.OFF;
    }
    trace(...x) {
        if (!this.enabledFor(this.TRACE))
            return;
        console.trace(...x);
        const sanitized = this.sanitizeArgs(x);
        this.iterateClients((client) => client.clientProvider.trace(...sanitized));
    }
    debug(...x) {
        if (!this.enabledFor(this.DEBUG))
            return;
        console.debug(...x);
        const sanitized = this.sanitizeArgs(x);
        this.iterateClients((client) => client.clientProvider.debug(...sanitized));
    }
    info(...x) {
        if (!this.enabledFor(this.INFO))
            return;
        console.info(...x);
        const sanitized = this.sanitizeArgs(x);
        this.iterateClients((client) => client.clientProvider.info(...sanitized));
    }
    log(...x) {
        if (!this.enabledFor(this.INFO))
            return;
        console.log(...x);
        const sanitized = this.sanitizeArgs(x);
        this.iterateClients((client) => client.clientProvider.log(...sanitized));
    }
    warn(...x) {
        if (!this.enabledFor(this.WARN))
            return;
        console.warn(...x);
        const sanitized = this.sanitizeArgs(x);
        this.iterateClients((client) => client.clientProvider.warn(...sanitized));
    }
    error(...x) {
        if (!this.enabledFor(this.ERROR))
            return;
        console.error(...x);
        const sanitized = this.sanitizeArgs(x);
        this.iterateClients((client) => client.clientProvider.error(...sanitized));
    }
    time(label) {
        if (!this.enabledFor(this.TIME))
            return;
        console.time(label);
        this.iterateClients((client) => client.clientProvider.time(label));
    }
    timeEnd(label) {
        if (!this.enabledFor(this.TIME))
            return;
        console.timeEnd(label);
        this.iterateClients((client) => client.clientProvider.timeEnd(label));
    }
    /**
     * Set the global log level.
     */
    setLevel(level) {
        this.currentLevel = level;
    }
    /**
     * Get the current log level.
     */
    getLevel() {
        return this.currentLevel;
    }
    /**
     * Returns true if the given level is enabled.
     */
    enabledFor(level) {
        return level.value >= this.currentLevel.value;
    }
    /**
     * Iterates all clients, catches individual client exceptions
     * and proceeds to execute for all clients.
     */
    async iterateClients(callback) {
        for (const client of this.clients) {
            try {
                await callback(client);
            }
            catch (ex) {
                console.error('Caught exception when iterating client', ex);
            }
        }
    }
    /**
     * Guards against any logging errors.
     * We don't want a logging exception to cause further issues upstream
     */
    sanitizeArgs(x) {
        const sanitizedParams = x.map((param) => {
            try {
                // Try and clone here first. If it fails it won't be passable over a MessagePort
                return structuredClone(param);
            }
            catch (ex) {
                console.error(ex);
                return 'Could not serialize log params. Check shared worker logs for more details.';
            }
        });
        return sanitizedParams;
    }
}
