import { DeckDescriptor } from './DeckDescriptor' ; import { SetArrays } from 'polar-shared/src/util/SetArrays' ; import { CreateDeckClient , ICreateDeckClient } from './clients/CreateDeckClient' ; import { DeckNamesAndIdsClient , IDeckNamesAndIdsClient } from './clients/DeckNamesAndIdsClient' ; import { Logger } from 'polar-shared/src/logger/Logger' ; import { SyncQueue } from '../SyncQueue' ; import { Optional } from 'polar-shared/src/util/ts/Optional' ; import { SyncTaskResult } from '../SyncTask' ; const log = Logger . create ( ) ; /**
 * Code that synchronizes decks by creating new decks when the required decks
 * are missing.
 */ export class DecksSync { public createDeckClient : ICreateDeckClient = new CreateDeckClient ( ) ; public deckNamesAndIdsClient : IDeckNamesAndIdsClient = new DeckNamesAndIdsClient ( ) ; private readonly missingDecks : string [ ] = [ ] ; private readonly missingDeckDescriptors : DeckDescriptor [ ] = [ ] ; private readonly syncQueue : SyncQueue ; param syncQueue constructor ( syncQueue ) { this . syncQueue = syncQueue ; } param deckDescriptors public enqueue ( deckDescriptors ) { this . syncQueue . add ( async ( ) => { return await this . findExistingDecks ( deckDescriptors ) ; } ) ; this . syncQueue . add ( async ( ) => { return await this . createMissingDecks ( ) ; } ) ; return this . missingDeckDescriptors ; } private async findExistingDecks ( deckDescriptors ) { log . info ( "Fetching existing decks for deckDescriptors: " , deckDescriptors ) ; const deckNamesAndIds = await this . deckNamesAndIdsClient . execute ( ) ; const currentDecks = Object . keys ( deckNamesAndIds ) ; const expectedDecks = deckDescriptors . map ( current => current . name ) ; this . missingDecks . push ( ... SetArrays . difference ( expectedDecks , currentDecks ) ) ; const message = `Found ${ this . missingDecks . length } missing decks from a total of ${ currentDecks . length }` ; log . info ( message ) ; this . missingDeckDescriptors . push ( ... this . missingDecks . map ( name => < DeckDescriptor > { name } ) ) ; return Optional . of ( { message } ) ; } private async createMissingDecks ( ) { this . missingDecks . forEach ( missingDeck => { this . syncQueue . add ( async ( ) => { return await this . createMissingDeck ( missingDeck ) ; } ) ; } ) ; const message = `Creating ${ this . missingDecks . length } decks.` ; return Optional . of ( { message } ) ; } private async createMissingDeck ( missingDeck ) { const message = `Creating missing deck: ${ missingDeck }` ; log . info ( message ) ; await this . createDeckClient . execute ( missingDeck ) ; return Optional . of ( { message } ) ; } }