/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Tiles
 */
import { assert, Dictionary } from "@itwin/core-bentley";
import { RenderSchedule } from "@itwin/core-common";
import { createWorkerProxy } from "../../common/WorkerProxy";
import { parseImdlDocument } from "../../common/imdl/ParseImdlDocument";
import { IModelApp } from "../../IModelApp";
export function acquireImdlParser(args) {
    const timeline = args.timeline;
    if (args.noWorker) {
        return {
            parse: async (options) => parseImdlDocument({
                ...options,
                timeline,
            }),
            release: () => undefined,
        };
    }
    if (!args.timeline) {
        if (!defaultParser) {
            const worker = createWorkerProxy(`${IModelApp.publicPath}scripts/parse-imdl-worker.js`);
            defaultParser = {
                parse: async (options) => worker.parse(options, [options.data.buffer]),
                release: () => undefined,
            };
        }
        return defaultParser;
    }
    let parser = parsersWithTimelines.get(args.timeline);
    if (!parser)
        parsersWithTimelines.set(args.timeline, parser = new ParserWithTimeline(args.timeline));
    assert(parser.refCount >= 0);
    ++parser.refCount;
    return parser;
}
let defaultParser;
class ParserWithTimeline {
    refCount = 0;
    _timeline;
    _worker;
    constructor(timeline) {
        this._timeline = timeline;
        this._worker = createWorkerProxy(`${IModelApp.publicPath}scripts/parse-imdl-worker.js`);
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
        this._worker.setTimeline(timeline.toJSON());
    }
    async parse(options) {
        return this._worker.parse(options, [options.data.buffer]);
    }
    release() {
        assert(this.refCount > 0);
        --this.refCount;
        if (this.refCount === 0) {
            parsersWithTimelines.delete(this._timeline);
            this._worker.terminate();
        }
    }
}
const parsersWithTimelines = new Dictionary((lhs, rhs) => {
    if (lhs instanceof RenderSchedule.ModelTimeline)
        return rhs instanceof RenderSchedule.ModelTimeline ? lhs.compareTo(rhs) : -1;
    return rhs instanceof RenderSchedule.Script ? lhs.compareTo(rhs) : 1;
});
//# sourceMappingURL=ImdlParser.js.map