/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { Logger, LogLevel } from "@itwin/core-bentley";
/**
 * SequentialLogMatcher match log messages in order and remove them from the list. Any test using
 * should check if length come down to zero. If its not then test should fail.
 */
export class SequentialLogMatcher extends Logger {
    _suppressMatchLogMsgs;
    _rules = [];
    _originalLogError;
    _originalLogWarning;
    _originalLogInfo;
    _originalLogTrace;
    allow(level, category, message) {
        if (this._rules.length === 0)
            return true;
        const rule = this._rules[0];
        if (rule.test(level, category, message)) {
            this._rules.shift();
            return this._suppressMatchLogMsgs === false;
        }
        return true;
    }
    constructor(_suppressMatchLogMsgs = true) {
        super();
        this._suppressMatchLogMsgs = _suppressMatchLogMsgs;
        this._originalLogError = Logger._logError;
        this._originalLogWarning = Logger._logWarning;
        this._originalLogInfo = Logger._logInfo;
        this._originalLogTrace = Logger._logTrace;
        Logger._logError = (category, message, metaData) => {
            if (this.allow(LogLevel.Error, category, message))
                this._originalLogError?.(category, message, metaData);
        };
        Logger._logWarning = (category, message, metaData) => {
            if (this.allow(LogLevel.Warning, category, message))
                this._originalLogWarning?.(category, message, metaData);
        };
        Logger._logInfo = (category, message, metaData) => {
            if (this.allow(LogLevel.Info, category, message))
                this._originalLogInfo?.(category, message, metaData);
        };
        Logger._logTrace = (category, message, metaData) => {
            if (this.allow(LogLevel.Trace, category, message))
                this._originalLogTrace?.(category, message, metaData);
        };
    }
    append() {
        const newMatch = new LogMatchRule();
        this._rules.push(newMatch);
        return newMatch;
    }
    finish() {
        return this.length === 0;
    }
    finishAndDispose() {
        const rc = this.finish();
        Logger._logError = this._originalLogError;
        Logger._logWarning = this._originalLogWarning;
        Logger._logInfo = this._originalLogInfo;
        Logger._logTrace = this._originalLogTrace;
        return rc;
    }
    get length() { return this._rules.length; }
}
export class LogMatchRule {
    _level;
    _category;
    _message;
    _metaDataCheck;
    test(level, category, message) {
        if (this._level) {
            if (this._level !== level)
                return false;
        }
        if (this._category) {
            if (this._category instanceof RegExp) {
                if (!this._category.test(category))
                    return false;
            }
            else {
                if (this._category !== category)
                    return false;
            }
        }
        if (this._message) {
            if (this._message instanceof RegExp) {
                if (!this._message.test(message))
                    return false;
            }
            else {
                if (this._message !== message)
                    return false;
            }
        }
        return true;
    }
    level(lvl) {
        this._level = lvl;
        return this;
    }
    trace() {
        return this.level(LogLevel.Trace);
    }
    error() {
        return this.level(LogLevel.Error);
    }
    info() {
        return this.level(LogLevel.Info);
    }
    warn() {
        return this.level(LogLevel.Warning);
    }
    category(category) {
        this._category = category;
        return this;
    }
    message(message) {
        this._message = message;
        return this;
    }
    metadata(check) {
        this._metaDataCheck = check;
        return this;
    }
}
//# sourceMappingURL=SequentialLogMatcher.js.map