import {Injectable} from "@angular/core";

import {
    ComponentLifecycleEventEmitter, Payload,
    TupleOfflineStorageNameService,
    TupleOfflineStorageService,
    TupleSelector,
    TupleStorageFactoryService
} from "@synerty/vortexjs";

import {branchLocalStorageName, diagramTuplePrefix} from "../PluginNames";
import {BranchTuple} from "../branch/BranchTuple";
import {PrivateDiagramBranchContext} from "../branch";


// ----------------------------------------------------------------------------
/** LocallyStoredBranchTupleSelector
 *
 * This is just a short cut for the tuple selector
 */

class LocallyStoredBranchTupleSelector extends TupleSelector {

    constructor(private modelSetKey: string,
                private key: string) {
        super(diagramTuplePrefix + "BranchTuple.LocallyStored", {
            modelSetKey: modelSetKey,
            key: key
        });
    }

}

// ----------------------------------------------------------------------------
/** Local Branch Storage Service
 *
 * This class manages storing of branches locally, this allows branches to
 * be created and edited offline.
 *
 * 1) Maintain a local storage of the BranchTuple
 *
 */
@Injectable()
export class LocalBranchStorageService extends ComponentLifecycleEventEmitter {
    private storage: TupleOfflineStorageService;

    constructor(storageFactory: TupleStorageFactoryService) {
        super();

        this.storage = new TupleOfflineStorageService(
            storageFactory,
            new TupleOfflineStorageNameService(branchLocalStorageName)
        );


    }


    /** Get Branch
     *
     * Get the objects with matching key from the index..
     *
     */
    loadBranch(modelSetKey: string, coordSetId: number, key: string): Promise<BranchTuple | null> {
        let prom: any = this.loadBranches(modelSetKey, key)
            .then((branches: BranchTuple[]) => {
                for (let branch of branches) {
                    if (branch.coordSetId == coordSetId)
                        return branch;
                }
            });
        return prom;
    }


    /** Get Branches
     *
     * Get the branches with the matching
     *
     */
    loadBranches(modelSetKey: string, key: string): Promise<BranchTuple[]> {
        let ts = new LocallyStoredBranchTupleSelector(modelSetKey, key);
        let prom: any = this.storage.loadTuples(ts);

        return prom;
    }


    saveBranch(branchContext: PrivateDiagramBranchContext): Promise<void> {
        let branchToSave: BranchTuple = branchContext["branch"];
        let ts = new LocallyStoredBranchTupleSelector(
            branchContext.modelSetKey,
            branchContext.key);
        let prom: any = this.loadBranches(branchContext.modelSetKey, branchToSave.key)
            .then((branches: BranchTuple[]) => {
                // Iterate though and update
                let updated = false;
                for (let i = 0; i < branches.length; i++) {
                    if (branches[i].key == branchToSave.key) {
                        branches[i] = branchToSave;
                        updated = true;
                        break;
                    }
                }

                // If we couldn't find it, then add it
                if (!updated)
                    branches.push(branchToSave);

                return this.storage.saveTuples(ts, branches);
            });
        return prom;
    }


}