import { assert } from "../../core/assert.js";
import { LogLevel } from "./LogLevel.js";

export class Logger {
    /**
     *
     * @private
     * @type {LoggerBackend[]}
     */
    backends = [];

    /**
     * Add a logging backend, this is a structure that handles incoming log messages.
     * There can be multiple backends registered at any given time or even none at all
     * @param {LoggerBackend} backend
     * @returns {boolean} will return false if backend instance is already attached
     */
    addBackend(backend) {
        if (this.backends.includes(backend)) {
            // already registered
            return false;
        }

        this.backends.push(backend);
        return true;
    }

    /**
     * Remove backend instance, counterpart to {@link #addBackend} see {@link #addBackend} for more information
     * @param {LoggerBackend} backend
     * @return {boolean}
     */
    removeBackend(backend) {
        const i = this.backends.indexOf(backend);
        if (i === -1) {
            return false;
        } else {
            this.backends.splice(i, 1);
            return true;
        }
    }

    /**
     *
     * @param {LogLevel|number} level
     * @param {string} message
     */
    log(level, message) {
        assert.enum(level, LogLevel, 'level');

        const backends = this.backends;
        const n = backends.length;

        for (let i = 0; i < n; i++) {
            const backend = backends[i];

            if (level > backend.getLevel()) {
                // skip, message level is too low level for this backend
                continue;
            }

            // forward the message to the backend
            backend.log(level, message);
        }
    }

    info(msg) {
        this.log(LogLevel.Info, msg);
    }

    warn(msg) {
        this.log(LogLevel.Warning, msg);
    }

    error(msg) {
        this.log(LogLevel.Error, msg);
    }
}
