import { TableRowSelectionMode } from '../types';
/**
 * Helper class for the nimble-table to validate that the table's configuration
 * is valid and report which aspects of the configuration are valid or invalid.
 */
export class TableValidator {
    constructor() {
        this.duplicateRecordId = false;
        this.missingRecordId = false;
        this.invalidRecordId = false;
        this.duplicateColumnId = false;
        this.missingColumnId = false;
        this.duplicateSortIndex = false;
        this.duplicateGroupIndex = false;
        this.idFieldNameNotConfigured = false;
        this.invalidColumnConfiguration = false;
        this.invalidParentIdConfiguration = false;
        this.recordIds = new Set();
    }
    getValidity() {
        return {
            duplicateRecordId: this.duplicateRecordId,
            missingRecordId: this.missingRecordId,
            invalidRecordId: this.invalidRecordId,
            duplicateColumnId: this.duplicateColumnId,
            missingColumnId: this.missingColumnId,
            duplicateSortIndex: this.duplicateSortIndex,
            duplicateGroupIndex: this.duplicateGroupIndex,
            idFieldNameNotConfigured: this.idFieldNameNotConfigured,
            invalidColumnConfiguration: this.invalidColumnConfiguration,
            invalidParentIdConfiguration: this.invalidParentIdConfiguration
        };
    }
    isValid() {
        return Object.values(this.getValidity()).every(x => !x);
    }
    areRecordIdsValid() {
        const validity = this.getValidity();
        return (!validity.duplicateRecordId
            && !validity.missingRecordId
            && !validity.invalidRecordId);
    }
    validateIdFieldConfiguration(selectionMode, idFieldName, parentIdFieldName) {
        const idFieldNameRequired = selectionMode !== TableRowSelectionMode.none
            || typeof parentIdFieldName === 'string';
        if (idFieldNameRequired) {
            this.idFieldNameNotConfigured = typeof idFieldName !== 'string';
        }
        else {
            this.idFieldNameNotConfigured = false;
        }
        return !this.idFieldNameNotConfigured;
    }
    validateRecordIds(data, idFieldName) {
        // Start off by assuming all IDs are valid.
        this.duplicateRecordId = false;
        this.missingRecordId = false;
        this.invalidRecordId = false;
        this.recordIds.clear();
        if (typeof idFieldName !== 'string') {
            return true;
        }
        for (const record of data) {
            if (!Object.prototype.hasOwnProperty.call(record, idFieldName)) {
                this.missingRecordId = true;
                continue;
            }
            const id = record[idFieldName];
            if (typeof id !== 'string') {
                this.invalidRecordId = true;
                continue;
            }
            if (this.recordIds.has(id)) {
                this.duplicateRecordId = true;
            }
            this.recordIds.add(id);
        }
        return (!this.missingRecordId
            && !this.invalidRecordId
            && !this.duplicateRecordId);
    }
    validateColumnIds(columnIds) {
        this.missingColumnId = false;
        this.duplicateColumnId = false;
        const anyColumnsHaveIds = columnIds.some(id => id);
        if (!anyColumnsHaveIds) {
            return true;
        }
        const idSet = new Set();
        for (const columnId of columnIds) {
            if (!columnId) {
                this.missingColumnId = true;
                continue;
            }
            if (idSet.has(columnId)) {
                this.duplicateColumnId = true;
            }
            idSet.add(columnId);
        }
        return !this.missingColumnId && !this.duplicateColumnId;
    }
    validateColumnSortIndices(sortIndices) {
        this.duplicateSortIndex = !this.validateIndicesAreUnique(sortIndices);
        return !this.duplicateSortIndex;
    }
    validateColumnGroupIndices(groupIndices) {
        this.duplicateGroupIndex = !this.validateIndicesAreUnique(groupIndices);
        return !this.duplicateGroupIndex;
    }
    validateColumnConfigurations(columns) {
        this.invalidColumnConfiguration = columns.some(x => !x.columnInternals.validator.isColumnValid);
        return !this.invalidColumnConfiguration;
    }
    getPresentRecordIds(requestedRecordIds) {
        return requestedRecordIds.filter(id => this.recordIds.has(id));
    }
    getOptionsWithPresentIds(requestedOptions) {
        return requestedOptions.filter(item => this.recordIds.has(item.recordId));
    }
    setParentIdConfigurationValidity(valid) {
        this.invalidParentIdConfiguration = !valid;
    }
    validateIndicesAreUnique(indices) {
        const numberSet = new Set(indices);
        return numberSet.size === indices.length;
    }
}
//# sourceMappingURL=table-validator.js.map