text: /**
   * @name SavedVis
   *
   * @extends SavedObject.
   *
   * NOTE: It's a type of SavedObject, but specific to visualizations.
   */
  
  import _ from 'lodash';
  import VisProvider from 'ui/vis';
  import uiModules from 'ui/modules';
  
  uiModules
  .get('app/visualize')
  .factory('SavedVis', function (config, $injector, courier, Promise, savedSearches, Private) {
    const Vis = Private(VisProvider);
  
    _.class(SavedVis).inherits(courier.SavedObject);
    function SavedVis(opts) {
      const self = this;
      opts = opts || {};
      if (typeof opts !== 'object') opts = { id: opts };
  
      SavedVis.Super.call(self, {
        type: SavedVis.type,
        mapping: SavedVis.mapping,
        searchSource: SavedVis.searchSource,
  
        id: opts.id,
        indexPattern: opts.indexPattern,
        defaults: {
          title: 'New Visualization',
          visState: (function () {
            if (!opts.type) return null;
            const def = {};
            def.type = opts.type;
            return def;
          }()),
          uiStateJSON: '{}',
          description: '',
          savedSearchId: opts.savedSearchId,
          version: 1
        },
  
        afterESResp: this._afterEsResp
      });
    }
  
    SavedVis.type = 'visualization';
  
    SavedVis.mapping = {
      title: 'text',
      visState: 'json',
      uiStateJSON: 'text',
      description: 'text',
      savedSearchId: 'keyword',
      version: 'integer'
    };
  
    // Order these fields to the top, the rest are alphabetical
    SavedVis.fieldOrder = ['title', 'description'];
  
    SavedVis.searchSource = true;
  
    SavedVis.prototype._afterEsResp = function () {
      const self = this;
  
      return self._getLinkedSavedSearch()
      .then(function () {
        self.searchSource.size(0);
  
        return self.vis ? self._updateVis() : self._createVis();
      })
      .then(function () {
        self.searchSource.aggs(function () {
          self.vis.requesting();
          return self.vis.aggs.toDsl();
        });
  
        return self;
      });
    };
  
    SavedVis.prototype._getLinkedSavedSearch = Promise.method(function () {
      const self = this;
      const linkedSearch = !!self.savedSearchId;
      const current = self.savedSearch;
  
      if (linkedSearch && current && current.id === self.savedSearchId) {
        return;
      }
  
      if (self.savedSearch) {
        self.searchSource.inherits(self.savedSearch.searchSource.getParent());
        self.savedSearch.destroy();
        self.savedSearch = null;
      }
  
      if (linkedSearch) {
        return savedSearches.get(self.savedSearchId)
        .then(function (savedSearch) {
          self.savedSearch = savedSearch;
          self.searchSource.inherits(self.savedSearch.searchSource);
        });
      }
    });
  
    SavedVis.prototype._createVis = function () {
      const self = this;
  
      if (self.stateJSON) {
        self.visState = Vis.convertOldState(self.typeName, JSON.parse(self.stateJSON));
      }
  
      // visState doesn't yet exist when importing a visualization, so we can't
      // assume that exists at this point. If it does exist, then we're not
      // importing a visualization, so we want to sync the title.
      if (self.visState) {
        self.visState.title = self.title;
      }
      self.vis = new Vis(
        self.searchSource.get('index'),
        self.visState
      );
  
      return self.vis;
    };
  
    SavedVis.prototype._updateVis = function () {
      const self = this;
  
      self.vis.indexPattern = self.searchSource.get('index');
      self.visState.title = self.title;
      self.vis.setState(self.visState);
    };
  
    return SavedVis;
  });
  