"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PartitionType = exports.TimeIntervalUnit = exports.ensureCatalogTimestampDomainsKey = exports.catalogHasTimestampDomains = exports.setCatalogTimestampDomain = exports.getCatalogTimestampDomain = exports.WAREHOUSE_TIMESTAMP_DOMAINS_KEY = exports.getUserAttributeQueryTags = exports.sanitizeQueryTagValue = exports.sanitizeQueryTagKey = void 0;
const MAX_USER_ATTRIBUTE_QUERY_TAGS = 20;
const MAX_QUERY_TAG_KEY_LENGTH = 60;
const MAX_QUERY_TAG_VALUE_LENGTH = 60;
const USER_ATTRIBUTE_QUERY_TAG_PREFIX = 'user_attribute_';
const sanitizeQueryTagString = (value, fallback, maxLength) => value
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9_-]/g, '_')
    .substring(0, maxLength) || fallback;
const sanitizeQueryTagKey = (key) => sanitizeQueryTagString(key, 'empty_key', MAX_QUERY_TAG_KEY_LENGTH);
exports.sanitizeQueryTagKey = sanitizeQueryTagKey;
const sanitizeQueryTagValue = (value) => sanitizeQueryTagString(value, 'empty_value', MAX_QUERY_TAG_VALUE_LENGTH);
exports.sanitizeQueryTagValue = sanitizeQueryTagValue;
const getUserAttributeQueryTags = (userAttributes) => Object.fromEntries(Object.entries(userAttributes).reduce((acc, [name, values]) => {
    if (acc.length >= MAX_USER_ATTRIBUTE_QUERY_TAGS) {
        return acc;
    }
    const tagName = (0, exports.sanitizeQueryTagKey)(`${USER_ATTRIBUTE_QUERY_TAG_PREFIX}${name}`);
    const value = values
        .map((attribute) => attribute.trim())
        .filter(Boolean)
        .join(',')
        .trim();
    if (value) {
        acc.push([
            tagName,
            (0, exports.sanitizeQueryTagValue)(value),
        ]);
    }
    return acc;
}, []));
exports.getUserAttributeQueryTags = getUserAttributeQueryTags;
/**
 * Sparse sidecar of timestamp domains, keyed like the catalog itself. It
 * lives on the catalog under a reserved key next to the database keys, so it
 * survives the `cached_warehouse` JSON round-trip unchanged and is inert to
 * readers that only look up their own database names.
 */
exports.WAREHOUSE_TIMESTAMP_DOMAINS_KEY = '__lightdashTimestampDomains';
const getCatalogTimestampDomain = (catalog, database, schema, table, column) => catalog[exports.WAREHOUSE_TIMESTAMP_DOMAINS_KEY]?.[database]?.[schema]?.[table]?.[column];
exports.getCatalogTimestampDomain = getCatalogTimestampDomain;
const setCatalogTimestampDomain = (catalog, database, schema, table, column, timestampDomain) => {
    if (timestampDomain === undefined)
        return;
    const catalogWithDomains = catalog;
    const domains = catalogWithDomains[exports.WAREHOUSE_TIMESTAMP_DOMAINS_KEY] ?? {};
    catalogWithDomains[exports.WAREHOUSE_TIMESTAMP_DOMAINS_KEY] = domains;
    domains[database] = domains[database] ?? {};
    domains[database][schema] = domains[database][schema] ?? {};
    domains[database][schema][table] = domains[database][schema][table] ?? {};
    domains[database][schema][table][column] = timestampDomain;
};
exports.setCatalogTimestampDomain = setCatalogTimestampDomain;
/**
 * True when the catalog was produced by domain-aware code: the sidecar key is
 * present, even if empty. A missing key means a pre-domain cache that should
 * be refetched once so timestamp columns get classified.
 */
const catalogHasTimestampDomains = (catalog) => exports.WAREHOUSE_TIMESTAMP_DOMAINS_KEY in catalog;
exports.catalogHasTimestampDomains = catalogHasTimestampDomains;
/**
 * Stamps the (possibly empty) sidecar onto a freshly fetched catalog so
 * `catalogHasTimestampDomains` can tell it apart from a pre-domain cache —
 * clients only create the key when they classify at least one column.
 */
const ensureCatalogTimestampDomainsKey = (catalog) => {
    const catalogWithDomains = catalog;
    catalogWithDomains[exports.WAREHOUSE_TIMESTAMP_DOMAINS_KEY] =
        catalogWithDomains[exports.WAREHOUSE_TIMESTAMP_DOMAINS_KEY] ?? {};
};
exports.ensureCatalogTimestampDomainsKey = ensureCatalogTimestampDomainsKey;
var TimeIntervalUnit;
(function (TimeIntervalUnit) {
    TimeIntervalUnit["SECOND"] = "SECOND";
    TimeIntervalUnit["MINUTE"] = "MINUTE";
    TimeIntervalUnit["HOUR"] = "HOUR";
    TimeIntervalUnit["DAY"] = "DAY";
    TimeIntervalUnit["WEEK"] = "WEEK";
    TimeIntervalUnit["MONTH"] = "MONTH";
    TimeIntervalUnit["YEAR"] = "YEAR";
})(TimeIntervalUnit || (exports.TimeIntervalUnit = TimeIntervalUnit = {}));
var PartitionType;
(function (PartitionType) {
    PartitionType["DATE"] = "DATE";
    PartitionType["RANGE"] = "RANGE";
})(PartitionType || (exports.PartitionType = PartitionType = {}));
//# sourceMappingURL=warehouse.js.map