"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.backupAppDataUseCase = void 0;
const rxjs_1 = require("rxjs");
const types_1 = require("./types");
/**
 * Backs up the application data for a specific app on a Ledger device. All interactions
 * with the storage provider are handled by this function.
 *
 * @param storageProvider - The storage provider object used for storing the backup data.
 * @param appName - The name of the application to backup.
 * @param backupAppDataFn - The function that returns observable for the backup process.
 * @returns An observable that emits BackupAppDataEvent during the backup process.
 * @throws {BackupAppDataError}
 */
function backupAppDataUseCase(appName, deviceModelId, storageProvider, backupAppDataFn) {
    let appDataInfo;
    const obs = backupAppDataFn().pipe((0, rxjs_1.switchMap)(async (event) => {
        switch (event.type) {
            case types_1.BackupAppDataEventType.AppDataInfoFetched: {
                const appStorage = await storageProvider.getItem(`${deviceModelId}-${appName}`);
                // Check if the app data is already backed up
                if (appStorage && appStorage.appDataInfo?.hash === event.data.hash) {
                    /**
                     * We cannot get the observer's complete callback here, so need to execute it manually if needed
                     */
                    return { type: types_1.BackupAppDataEventType.AppDataAlreadyBackedUp };
                }
                // If not, store the app data info and transfer the event
                appDataInfo = event.data;
                return event;
            }
            case types_1.BackupAppDataEventType.AppDataBackedUp:
                // Store the app data
                if (appDataInfo) {
                    await storageProvider.setItem(`${deviceModelId}-${appName}`, {
                        appDataInfo,
                        appData: event.data,
                    });
                }
                // Erase the app data, then return the event
                return { type: types_1.BackupAppDataEventType.AppDataBackedUp, data: "" };
            case types_1.BackupAppDataEventType.Progress:
            case types_1.BackupAppDataEventType.NoAppDataToBackup:
                return event;
            default:
                throw new types_1.BackupAppDataError("Invalid event type");
        }
    }));
    return obs;
}
exports.backupAppDataUseCase = backupAppDataUseCase;
//# sourceMappingURL=backupAppDataUseCase.js.map