import { Injectable } from '@angular/core' ; import { MmpService } from '../mmp/mmp.service' ; import { BehaviorSubject , Observable } from 'rxjs' ; import { StorageService } from '../storage/storage.service' ; import { CachedMap , CachedMapEntry } from '../../../shared/models/cached-map.model' ; @ Injectable ( { providedIn : 'root' } ) export class MapCacheService { public attachedMap : Observable < CachedMapEntry | null > ; private readonly windowTitle : string ; private readonly attachedMapSubject : BehaviorSubject < CachedMapEntry | null > ; constructor ( private mmpService , private storageService ) { this . windowTitle = window . document . title ; this . attachedMapSubject = new BehaviorSubject < CachedMapEntry | null > ( null ) ; this . attachedMap = this . attachedMapSubject . asObservable ( ) ; } /**
     * If there are cached maps, then attach the last cached map.
     * Otherwise set the attached map status to `null`.
     */ public async init ( ) { const storageEntries = await this . storageService . getAllEntries ( ) ; let lastCachedMap ; let lastCachedKey ; for ( const [ key , value ] of storageEntries ) { if ( key . includes ( 'map-' ) ) { if ( ! lastCachedMap || value . lastModified > lastCachedMap . lastModified ) { lastCachedMap = value ; lastCachedKey = key ; } } } if ( ! lastCachedMap ) { this . attachNewMap ( ) ; return ; } this . attachMap ( { key : lastCachedKey , cachedMap : lastCachedMap } ) ; this . mmpService . new ( lastCachedMap . data ) ; } /**
     * Add current new application map to cache and attach it.
     */ public async attachNewMap ( ) { const key = this . createKey ( ) ; const cachedMap = { data : this . mmpService . exportAsJSON ( ) , lastModified : Date . now ( ) } ; await this . storageService . set ( key , cachedMap ) ; this . attachMap ( { key , cachedMap } ) ; } /**
     * Attach a map.
     */ public attachMap ( cachedMapEntry ) { this . attachedMapSubject . next ( cachedMapEntry ) ; } /**
     * Update the attached map.
     */ public async updateAttachedMap ( ) { const cachedMapEntry = this . getAttachedMap ( ) ; const cachedMap = { data : this . mmpService . exportAsJSON ( ) , lastModified : Date . now ( ) } ; await this . storageService . set ( cachedMapEntry . key , cachedMap ) ; this . attachMap ( { key : cachedMapEntry . key , cachedMap } ) ; } /**
     * Remove a cached map from the storage.
     */ public async removeCachedMap ( key ) { await this . storageService . remove ( key ) ; } /**
     * Return all the cached map entries (cachedMap + key) of the storage.
     */ public async getCachedMapEntries ( ) { const storageEntries = await this . storageService . getAllEntries ( ) || [ ] ; return storageEntries . filter ( ( entry ) => { return entry [ 0 ] . includes ( 'map-' ) ; } ) . map ( ( entry ) => { return { key : entry [ 0 ] , cachedMap : entry [ 1 ] } ; } ) ; } /**
     * Return the attached cached map key, otherwise if there is no attached maps return `null`.
     */ public getAttachedMap ( ) { return this . attachedMapSubject . getValue ( ) ; } /**
     * Return the key of the map in the storage: `map-` + current timestamp.
     */ private createKey ( ) { return `map-${ Date . now ( ) . toString ( ) }` ; } }