/*
 * Copyright (c) 2025, Salesforce, Inc.
 * SPDX-License-Identifier: Apache-2
 * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
 */
/**
 * Parses a relative time string (e.g., "5m", "1h", "2d") into milliseconds.
 * Returns null if the string is not a valid relative time format.
 */
export function parseRelativeTime(timeStr) {
    const match = timeStr.match(/^(\d+)([mhd])$/i);
    if (!match) {
        return null;
    }
    const value = Number.parseInt(match[1], 10);
    const unit = match[2].toLowerCase();
    switch (unit) {
        case 'd': {
            return value * 24 * 60 * 60 * 1000;
        }
        case 'h': {
            return value * 60 * 60 * 1000;
        }
        case 'm': {
            return value * 60 * 1000;
        }
        default: {
            return null;
        }
    }
}
/**
 * Parses a `since` value into a Date object.
 * Supports:
 * - Relative times: "5m", "1h", "2d"
 * - ISO 8601: "2026-01-25T10:00:00"
 *
 * @param sinceStr - The value to parse
 * @param now - Reference time for relative values (defaults to the current time).
 *   Injectable so callers that resolve several bounds together, or that need
 *   deterministic behavior in tests, can pin a single "now".
 */
export function parseSinceTime(sinceStr, now = new Date()) {
    const relativeMs = parseRelativeTime(sinceStr);
    if (relativeMs !== null) {
        return new Date(now.getTime() - relativeMs);
    }
    const date = new Date(sinceStr);
    if (Number.isNaN(date.getTime())) {
        throw new TypeError(`Invalid --since value: "${sinceStr}". Use relative time (e.g., "5m", "1h", "2d") or ISO 8601 (e.g., "2026-01-25T10:00:00")`);
    }
    return date;
}
/**
 * Parses a B2C log timestamp into a Date object.
 * Expected format: "2025-01-25 10:30:45.123 GMT"
 */
export function parseLogTimestamp(timestamp) {
    const isoFormat = timestamp.replace(' GMT', 'Z').replace(' ', 'T');
    const date = new Date(isoFormat);
    return Number.isNaN(date.getTime()) ? null : date;
}
/**
 * Filters entries by timestamp.
 */
export function filterBySince(entries, since) {
    return entries.filter((entry) => {
        if (!entry.timestamp)
            return true;
        const entryDate = parseLogTimestamp(entry.timestamp);
        return entryDate === null || entryDate >= since;
    });
}
/**
 * Filters entries by log level.
 */
export function filterByLevel(entries, levels) {
    const upperLevels = new Set(levels.map((l) => l.toUpperCase()));
    return entries.filter((entry) => {
        if (!entry.level)
            return false;
        return upperLevels.has(entry.level.toUpperCase());
    });
}
/**
 * Filters entries by text search (case-insensitive substring match).
 */
export function filterBySearch(entries, search) {
    const lowerSearch = search.toLowerCase();
    return entries.filter((entry) => {
        return entry.message.toLowerCase().includes(lowerSearch) || entry.raw.toLowerCase().includes(lowerSearch);
    });
}
/**
 * Checks if a single entry matches the specified log levels.
 * Used for streaming/tail scenarios where we filter one entry at a time.
 */
export function matchesLevel(entry, levels) {
    if (!entry.level)
        return false;
    const upperLevels = new Set(levels.map((l) => l.toUpperCase()));
    return upperLevels.has(entry.level.toUpperCase());
}
/**
 * Checks if a single entry matches the search text (case-insensitive).
 * Used for streaming/tail scenarios where we filter one entry at a time.
 */
export function matchesSearch(entry, search) {
    const lowerSearch = search.toLowerCase();
    return entry.message.toLowerCase().includes(lowerSearch) || entry.raw.toLowerCase().includes(lowerSearch);
}
//# sourceMappingURL=filter.js.map