"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IModelSession = void 0;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
const chai_1 = require("chai");
const core_frontend_1 = require("@itwin/core-frontend");
const itwins_client_1 = require("@itwin/itwins-client");
const core_common_1 = require("@itwin/core-common");
const core_bentley_1 = require("@itwin/core-bentley");
const imodels_client_management_1 = require("@itwin/imodels-client-management");
class IModelSession {
    iTwinId;
    iModelId;
    changesetId;
    _imodelVersion;
    _iModel;
    constructor(iTwinId, imodelId, changesetId) {
        this.iTwinId = iTwinId;
        this.iModelId = imodelId;
        this.changesetId = changesetId;
        this._imodelVersion = changesetId ? core_common_1.IModelVersion.asOfChangeSet(changesetId) : core_common_1.IModelVersion.latest();
    }
    static async create(requestContext, iModelData) {
        let iTwinId;
        let imodelId;
        // Turn the iTwin name into an id
        if (iModelData.useITwinName) {
            if (!iModelData.iTwinName)
                throw new Error(`The iModel has no iTwin name, so it cannot get the iTwin.`);
            const client = new itwins_client_1.ITwinsAccessClient();
            const iTwinListResponse = await client.queryAsync(requestContext, itwins_client_1.ITwinSubClass.Project, {
                displayName: iModelData.iTwinName,
            });
            const iTwinList = iTwinListResponse.data;
            if (!iTwinList) {
                throw new Error(`ITwin ${iModelData.iTwinName} returned with no data when queried.`);
            }
            if (iTwinList.length === 0)
                throw new Error(`ITwin ${iModelData.iTwinName} was not found for the user.`);
            else if (iTwinList.length > 1)
                throw new Error(`Multiple iTwins named ${iModelData.iTwinName} were found for the user.`);
            iTwinId = iTwinList[0].id ?? iModelData.iTwinId;
        }
        else
            iTwinId = iModelData.iTwinId;
        if (iModelData.useName) {
            const imodelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${process.env.IMJS_URL_PREFIX ?? ""}api.bentley.com/imodels` } });
            const imodels = imodelClient.iModels.getRepresentationList({
                authorization: async () => {
                    const [scheme, token] = requestContext.split(" ");
                    if (!scheme || !token)
                        core_bentley_1.ITwinError.throwError({
                            iTwinErrorId: {
                                key: imodels_client_management_1.IModelsErrorCode.InvalidIModelsRequest,
                                scope: imodels_client_management_1.IModelsErrorScope,
                            },
                            message: "Unsupported access token format",
                        });
                    return Promise.resolve({ scheme, token });
                },
                urlParams: {
                    iTwinId,
                    name: iModelData.name,
                },
            });
            for await (const iModel of imodels) {
                imodelId = iModel.id;
                break;
            }
            if (!imodelId)
                throw new Error(`The iModel ${iModelData.name} does not exist in iTwin ${iTwinId}.`);
        }
        else
            imodelId = iModelData.id;
        console.log(`Using iModel { name:${iModelData.name}, id:${iModelData.id}, iTwinId:${iModelData.iTwinId}, changesetId:${iModelData.changeSetId} }`); // eslint-disable-line no-console
        return new IModelSession(iTwinId, imodelId, iModelData.changeSetId);
    }
    async getConnection() {
        return undefined === this._iModel ? this.open() : this._iModel;
    }
    async open() {
        try {
            // eslint-disable-next-line no-console
            console.log(`Environment: ${process.env.IMJS_URL_PREFIX}`);
            this._iModel = await core_frontend_1.CheckpointConnection.openRemote(this.iTwinId, this.iModelId, this._imodelVersion);
            (0, chai_1.expect)(this._iModel).to.exist;
        }
        catch (e) {
            throw new Error(`Failed to open test iModel. Error: ${e.message}`);
        }
        return this._iModel;
    }
}
exports.IModelSession = IModelSession;
//# sourceMappingURL=IModelSession.js.map