import { switchMap } from "rxjs";
import { BackupAppDataError, BackupAppDataEventType, } from "./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}
 */
export function backupAppDataUseCase(appName, deviceModelId, storageProvider, backupAppDataFn) {
    let appDataInfo;
    const obs = backupAppDataFn().pipe(switchMap(async (event) => {
        switch (event.type) {
            case 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: BackupAppDataEventType.AppDataAlreadyBackedUp };
                }
                // If not, store the app data info and transfer the event
                appDataInfo = event.data;
                return event;
            }
            case 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: BackupAppDataEventType.AppDataBackedUp, data: "" };
            case BackupAppDataEventType.Progress:
            case BackupAppDataEventType.NoAppDataToBackup:
                return event;
            default:
                throw new BackupAppDataError("Invalid event type");
        }
    }));
    return obs;
}
//# sourceMappingURL=backupAppDataUseCase.js.map