/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module IModelConnection
 */
import { CompressedId64Set } from "@itwin/core-bentley";
export class Metadata {
    constructor(name) {
        this.baseClasses = [];
        this.classFullName = name;
    }
    is(baseName) {
        return baseName === this.classFullName || this.baseClasses.some((base) => base.is(baseName));
    }
}
function* entityChangesIterator(changes, options) {
    let excludedMetaIndices;
    if (options?.includeMetadata) {
        for (let i = 0; i < changes.metadata.length; i++) {
            if (!options.includeMetadata(changes.metadata[i])) {
                excludedMetaIndices = excludedMetaIndices ?? new Set();
                excludedMetaIndices.add(i);
            }
        }
    }
    function* process(type) {
        if (options?.includeTypes && !options.includeTypes.includes(type)) {
            return;
        }
        const ids = changes[type];
        if (undefined === ids) {
            return;
        }
        const metaIndices = changes.args[`${type}Meta`];
        let index = 0;
        for (const id of CompressedId64Set.iterable(ids)) {
            const metaIndex = metaIndices[index++];
            if (excludedMetaIndices && excludedMetaIndices.has(metaIndex)) {
                continue;
            }
            const metadata = changes.metadata[metaIndex];
            yield { type, id, metadata };
        }
    }
    yield* process("inserted");
    yield* process("deleted");
    yield* process("updated");
}
export class EntityChanges {
    constructor(args) {
        this.args = args;
        this.metadata = args.meta.map((x) => new Metadata(x.name));
        for (let i = 0; i < this.metadata.length; i++) {
            const meta = this.metadata[i];
            for (const baseIndex of args.meta[i].bases) {
                meta.baseClasses.push(this.metadata[baseIndex]);
            }
        }
    }
    get inserted() { return this.args.inserted; }
    get deleted() { return this.args.deleted; }
    get updated() { return this.args.updated; }
    [Symbol.iterator]() {
        return entityChangesIterator(this);
    }
    filter(options) {
        return {
            [Symbol.iterator]: () => entityChangesIterator(this, options),
        };
    }
}
//# sourceMappingURL=TxnEntityChanges.js.map