"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module NativeApp
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.NativeHost = void 0;
const path_1 = require("path");
const core_bentley_1 = require("@itwin/core-bentley");
const core_common_1 = require("@itwin/core-common");
const BriefcaseManager_1 = require("./BriefcaseManager");
const CheckpointManager_1 = require("./CheckpointManager");
const IModelHost_1 = require("./IModelHost");
const IpcHost_1 = require("./IpcHost");
const NativeAppStorage_1 = require("./NativeAppStorage");
const CatalogDb_1 = require("./CatalogDb");
/**
 * Implementation of NativeAppFunctions
 */
class NativeAppHandler extends IpcHost_1.IpcHandler {
    get channelName() { return core_common_1.nativeAppIpcStrings.channelName; }
    async getAccessToken() {
        return IModelHost_1.IModelHost.authorizationClient?.getAccessToken();
    }
    async checkInternetConnectivity() {
        return NativeHost.checkInternetConnectivity();
    }
    async overrideInternetConnectivity(by, status) {
        NativeHost.overrideInternetConnectivity(by, status);
    }
    async acquireNewBriefcaseId(iModelId) {
        return BriefcaseManager_1.BriefcaseManager.acquireNewBriefcaseId({ iModelId });
    }
    async getBriefcaseFileName(props) {
        return BriefcaseManager_1.BriefcaseManager.getFileName(props);
    }
    async downloadBriefcase(request, reportProgress, progressInterval) {
        const args = {
            ...request,
            accessToken: await this.getAccessToken(),
            onProgress: (_a, _b) => checkAbort(),
        };
        const checkAbort = () => {
            (0, core_bentley_1.assert)(undefined !== args.fileName);
            const job = CheckpointManager_1.Downloads.isInProgress(args.fileName);
            return (job && job.request.abort === 1) ? CheckpointManager_1.ProgressStatus.Abort : CheckpointManager_1.ProgressStatus.Continue;
        };
        if (reportProgress) {
            const progressCallback = (loaded, total) => {
                IpcHost_1.IpcHost.send(`nativeApp.progress-${request.iModelId}`, { loaded, total });
                return checkAbort();
            };
            args.onProgress = (0, IpcHost_1.throttleProgressCallback)(progressCallback, checkAbort, progressInterval);
        }
        return BriefcaseManager_1.BriefcaseManager.downloadBriefcase(args);
    }
    async requestCancelDownloadBriefcase(fileName) {
        const job = CheckpointManager_1.Downloads.isInProgress(fileName);
        if (job)
            job.request.abort = 1;
        return job !== undefined;
    }
    async deleteBriefcaseFiles(fileName) {
        await BriefcaseManager_1.BriefcaseManager.deleteBriefcaseFiles(fileName, await IModelHost_1.IModelHost.getAccessToken());
    }
    async getCachedBriefcases(iModelId) {
        return BriefcaseManager_1.BriefcaseManager.getCachedBriefcases(iModelId);
    }
    async storageMgrOpen(storageId) {
        return NativeAppStorage_1.NativeAppStorage.open(storageId).id;
    }
    async storageMgrClose(storageId, deleteIt) {
        NativeAppStorage_1.NativeAppStorage.find(storageId).close(deleteIt);
    }
    async storageMgrNames() {
        return NativeAppStorage_1.NativeAppStorage.getStorageNames();
    }
    async storageGetValueType(storageId, key) {
        return NativeAppStorage_1.NativeAppStorage.find(storageId).getValueType(key);
    }
    async storageGet(storageId, key) {
        return NativeAppStorage_1.NativeAppStorage.find(storageId).getData(key);
    }
    async storageSet(storageId, key, value) {
        NativeAppStorage_1.NativeAppStorage.find(storageId).setData(key, value);
    }
    async storageRemove(storageId, key) {
        NativeAppStorage_1.NativeAppStorage.find(storageId).removeData(key);
    }
    async storageKeys(storageId) {
        return NativeAppStorage_1.NativeAppStorage.find(storageId).getKeys();
    }
    async storageRemoveAll(storageId) {
        NativeAppStorage_1.NativeAppStorage.find(storageId).removeAll();
    }
}
/**
 * Backend for desktop/mobile native applications
 * @public
 */
class NativeHost {
    static _reachability;
    static _applicationName;
    constructor() { } // no instances - static methods only
    /** Event called when the internet connectivity changes, if known. */
    static onInternetConnectivityChanged = new core_bentley_1.BeEvent();
    static _appSettingsCacheDir;
    /** Get the local cache folder for application settings */
    static get appSettingsCacheDir() {
        return this._appSettingsCacheDir ??= (0, path_1.join)(IModelHost_1.IModelHost.cacheDir, "appSettings");
    }
    /** Send a notification to the NativeApp connected to this NativeHost. */
    static notifyNativeFrontend(methodName, ...args) {
        return IpcHost_1.IpcHost.send(core_common_1.nativeAppIpcStrings.notifyChannel, methodName, ...args);
    }
    static _isValid = false;
    static get isValid() { return this._isValid; }
    static get applicationName() { return this._applicationName; }
    /** Get the settings store for this NativeHost. */
    static get settingsStore() {
        return NativeAppStorage_1.NativeAppStorage.open(this.applicationName);
    }
    /**
     * Start the backend of a native app.
     * @note this method calls [[IpcHost.startup]] internally.
     */
    static async startup(opt) {
        if (!this.isValid) {
            this._isValid = true;
            this.onInternetConnectivityChanged.addListener((status) => NativeHost.notifyNativeFrontend("notifyInternetConnectivityChanged", status));
            this._applicationName = opt?.nativeHost?.applicationName ?? "iTwinApp";
        }
        await IpcHost_1.IpcHost.startup(opt);
        if (IpcHost_1.IpcHost.isValid) { // for tests, we use NativeHost but don't have a frontend
            NativeAppHandler.register();
            CatalogDb_1.CatalogIModelHandler.register();
        }
    }
    /** Shutdown native app backend. Also calls [[IpcHost.shutdown]] */
    static async shutdown() {
        this._isValid = false;
        this.onInternetConnectivityChanged.clear();
        await IpcHost_1.IpcHost.shutdown();
    }
    /** get current value of internet connectivity */
    static checkInternetConnectivity() {
        return this._reachability ?? core_common_1.InternetConnectivityStatus.Online;
    }
    /**
     * Override internet connectivity state
     * @param _overridenBy who overrode the value.
     * @internal
     */
    static overrideInternetConnectivity(_overridenBy, status) {
        if (this._reachability !== status) {
            this._reachability = status;
            this.onInternetConnectivityChanged.raiseEvent(status);
        }
    }
}
exports.NativeHost = NativeHost;
//# sourceMappingURL=NativeHost.js.map