"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.integrityCheckTypeMap = void 0;
exports.getIntegrityCheckName = getIntegrityCheckName;
exports.performQuickIntegrityCheck = performQuickIntegrityCheck;
exports.performSpecificIntegrityCheck = performSpecificIntegrityCheck;
const core_bentley_1 = require("@itwin/core-bentley");
const core_common_1 = require("@itwin/core-common");
/**
 * Information about each integrity check type, including the name, expected result type, and SQL query to execute
 * @internal
 */
exports.integrityCheckTypeMap = {
    checkDataColumns: {
        name: "Check Data Columns",
        resultType: "CheckDataColumnsResultRow",
        sqlCommand: "check_data_columns",
        sqlQuery: `PRAGMA integrity_check(check_data_columns) options enable_experimental_features`,
    },
    checkECProfile: {
        name: "Check EC Profile",
        resultType: "CheckECProfileResultRow",
        sqlCommand: "check_ec_profile",
        sqlQuery: `PRAGMA integrity_check(check_ec_profile) options enable_experimental_features`,
    },
    checkNavigationClassIds: {
        name: "Check Navigation Class Ids",
        resultType: "CheckNavClassIdsResultRow",
        sqlCommand: "check_nav_class_ids",
        sqlQuery: `PRAGMA integrity_check(check_nav_class_ids) options enable_experimental_features`,
    },
    checkNavigationIds: {
        name: "Check Navigation Ids",
        resultType: "CheckNavIdsResultRow",
        sqlCommand: "check_nav_ids",
        sqlQuery: `PRAGMA integrity_check(check_nav_ids) options enable_experimental_features`,
    },
    checkLinktableForeignKeyClassIds: {
        name: "Check Link Table Foreign Key Class Ids",
        resultType: "CheckLinkTableFkClassIdsResultRow",
        sqlCommand: "check_linktable_fk_class_ids",
        sqlQuery: `PRAGMA integrity_check(check_linktable_fk_class_ids) options enable_experimental_features`,
    },
    checkLinktableForeignKeyIds: {
        name: "Check Link Table Foreign Key Ids",
        resultType: "CheckLinkTableFkIdsResultRow",
        sqlCommand: "check_linktable_fk_ids",
        sqlQuery: `PRAGMA integrity_check(check_linktable_fk_ids) options enable_experimental_features`,
    },
    checkClassIds: {
        name: "Check Class Ids",
        resultType: "CheckClassIdsResultRow",
        sqlCommand: "check_class_ids",
        sqlQuery: `PRAGMA integrity_check(check_class_ids) options enable_experimental_features`,
    },
    checkDataSchema: {
        name: "Check Data Schema",
        resultType: "CheckDataSchemaResultRow",
        sqlCommand: "check_data_schema",
        sqlQuery: `PRAGMA integrity_check(check_data_schema) options enable_experimental_features`,
    },
    checkSchemaLoad: {
        name: "Check Schema Load",
        resultType: "CheckSchemaLoadResultRow",
        sqlCommand: "check_schema_load",
        sqlQuery: `PRAGMA integrity_check(check_schema_load) options enable_experimental_features`,
    },
    checkMissingChildRows: {
        name: "Check Missing Child Rows",
        resultType: "CheckMissingChildRowsResultRow",
        sqlCommand: "check_missing_child_rows",
        sqlQuery: `PRAGMA integrity_check(check_missing_child_rows) options enable_experimental_features`,
    },
};
/**
 * Gets the user-friendly name of an integrity check based on its key or SQL command.
 * It first attempts to find a direct match for the key in the integrityCheckTypeMap. If not found, it searches for a match based on the SQL command.
 * If still not found, it returns the original check string.
 * @param check - The integrity check key or SQL command to get the name of
 * @returns The user-friendly name of the integrity check, or the original check string if no match is found
 * @internal
 */
function getIntegrityCheckName(check) {
    // First try direct lookup by key
    const directLookup = exports.integrityCheckTypeMap[check];
    if (directLookup) {
        return directLookup.name;
    }
    // If not found, search by sqlCommand
    for (const [, value] of Object.entries(exports.integrityCheckTypeMap)) {
        if (value.sqlCommand === check) {
            return value.name;
        }
    }
    // Fallback to the original check string
    return check;
}
/**
 * Performs a quick integrity check on the given iModel.
 * @param iModel The IModelDb instance to perform the integrity check on
 * @returns An array of results for each check performed, including the check name, whether it passed, and the elapsed time in seconds
 * @internal
 */
async function performQuickIntegrityCheck(iModel) {
    const integrityCheckQuery = "PRAGMA integrity_check options enable_experimental_features";
    const integrityCheckResults = [];
    for await (const row of iModel.createQueryReader(integrityCheckQuery)) {
        integrityCheckResults.push({ check: getIntegrityCheckName(row.check), passed: row.result, elapsedSeconds: row.elapsed_sec });
    }
    ;
    return integrityCheckResults;
}
async function performSpecificIntegrityCheck(iModel, check) {
    switch (check) {
        case "checkDataColumns": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkDataColumns.sqlQuery)) {
                results.push({ sno: row.sno, table: row.table, column: row.column });
            }
            return results;
        }
        case "checkECProfile": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkECProfile.sqlQuery)) {
                results.push({ sno: row.sno, type: row.type, name: row.name, issue: row.issue });
            }
            return results;
        }
        case "checkNavigationClassIds": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkNavigationClassIds.sqlQuery)) {
                results.push({ sno: row.sno, id: row.id, class: row.class, property: row.property, navId: row.nav_id, navClassId: row.nav_classId });
            }
            return results;
        }
        case "checkNavigationIds": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkNavigationIds.sqlQuery)) {
                results.push({ sno: row.sno, id: row.id, class: row.class, property: row.property, navId: row.nav_id, primaryClass: row.primary_class });
            }
            return results;
        }
        case "checkLinktableForeignKeyClassIds": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkLinktableForeignKeyClassIds.sqlQuery)) {
                results.push({ sno: row.sno, id: row.id, relationship: row.relationship, property: row.property, keyId: row.key_id, keyClassId: row.key_classId });
            }
            return results;
        }
        case "checkLinktableForeignKeyIds": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkLinktableForeignKeyIds.sqlQuery)) {
                results.push({ sno: row.sno, id: row.id, relationship: row.relationship, property: row.property, keyId: row.key_id, primaryClass: row.primary_class });
            }
            return results;
        }
        case "checkClassIds": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkClassIds.sqlQuery)) {
                results.push({ sno: row.sno, class: row.class, id: row.id, classId: row.class_id, type: row.type });
            }
            return results;
        }
        case "checkDataSchema": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkDataSchema.sqlQuery)) {
                results.push({ sno: row.sno, type: row.type, name: row.name });
            }
            return results;
        }
        case "checkSchemaLoad": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkSchemaLoad.sqlQuery)) {
                results.push({ sno: row.sno, schema: row.schema });
            }
            return results;
        }
        case "checkMissingChildRows": {
            const results = [];
            for await (const row of iModel.createQueryReader(exports.integrityCheckTypeMap.checkMissingChildRows.sqlQuery)) {
                results.push({ sno: row.sno, class: row.class, id: row.id, classId: row.class_id, missingRowInTables: row.MissingRowInTables });
            }
            return results;
        }
        default:
            throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, `Unknown integrity check type: ${check}`);
    }
}
//# sourceMappingURL=IntegrityCheck.js.map