text: import Destroyable from '../model/destroyable';
  import LocalReference from '../model/reference/local-reference';
  import PersistedReference from '../model/reference/persisted-reference';
  import InternalDocument from '../model/internal-document';
  import pathFromOptions from '../util/path-from-options';
  
  export default class DocumentsManager extends Destroyable {
  
    constructor(context) {
      super();
      this.context = context;
    }
  
    createInternalData(json, format) {
      return this.context.dataManager.createInternal(json, format);
    }
  
    createLocalReference({ id, collection, path }) {
      return new LocalReference(id, collection, path);
    }
  
    createPersistedReferenceWithRef(ref) {
      return new PersistedReference(this.context, ref);
    }
  
    createPersistedReferenceWithPath(path) {
      let ref = this.context.firestore.doc(path);
      return this.createPersistedReferenceWithRef(ref);
    }
  
    createInternalDocument(reference, data, state) {
      return new InternalDocument(this.context, reference, data, state);
    }
  
    // { id, collection, path, data }
    createNewInternalDocument(opts) {
      let reference = this.createLocalReference(opts);
      let data = this.createInternalData(opts.data, 'model');
      let internal = this.createInternalDocument(reference, data);
      this.context.identity.documents.storeLocalInternalDocument(internal);
      return internal;
    }
  
    // { collection, data }
    createAutogeneratedInternalDocument(opts) {
      let { collection, data } = opts;
      let ref = this.context.firestore.collection(collection).doc();
      return this.loadedInternalDocument(ref, false, data, 'model');
    }
  
    // { id, collection, path, data, create }
    existingInternalDocument(opts) {
      let path = pathFromOptions(opts);
      let identity = this.context.identity.documents;
      let internal = identity.persistedInternalDocument(path);
      if(!internal && opts.create) {
        let reference = this.createPersistedReferenceWithPath(path);
        let data = this.createInternalData(opts.data, 'model');
        internal = this.createInternalDocument(reference, data, { isDirty: false, isLoading: true, isLoaded: false });
        identity.storePersistedInternalDocument(internal);
      }
      return internal;
    }
  
    loadedInternalDocument(ref, exists, json, format) {
      let path = ref.path;
      let identity = this.context.identity.documents;
      let internal = identity.persistedInternalDocument(path);
      if(!internal) {
        let reference = this.createPersistedReferenceWithRef(ref);
        let data = this.createInternalData(json, format);
        internal = this.createInternalDocument(reference, data, { isDirty: false, isLoading: false, isLoaded: true, isExisting: exists });
        identity.storePersistedInternalDocument(internal);
      }
      return internal;
    }
  
    loadedInternalDocumentForSnapshot(snapshot) {
      let ref = snapshot.ref;
      let exists = snapshot.exists;
      let data = snapshot.data({ serverTimestamps: 'estimate' });
      return this.loadedInternalDocument(ref, exists, data, 'storage');
    }
  
    localInternalDocumentDidSave(internal) {
      let context = this.context;
      context.identity.documents.storePersistedInternalDocument(internal);
      context.localInternalDocumentDidSave(internal);
    }
  
    internalDocumentWillDestroy(internal) {
      let context = this.context;
      context.identity.documents.removeInternalDocument(internal);
      context.internalDocumentWillDestroy(internal);
    }
  
  }
  