"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.loadAndResolveDataView = void 0;
exports.loadDataView = loadDataView;
exports.resolveDataView = resolveDataView;
var _i18n = require("@kbn/i18n");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

/**
 * Function to load the given data view by id, providing a fallback if it doesn't exist
 */
async function loadDataView({
  id,
  dataViewSpec,
  services,
  dataViewList
}) {
  const {
    dataViews
  } = services;
  let fetchId = id;

  /**
   * Handle redirect with data view spec provided via history location state
   */
  if (dataViewSpec) {
    const isPersisted = dataViewList.find(({
      id: currentId
    }) => currentId === dataViewSpec.id);
    if (!isPersisted) {
      const createdAdHocDataView = await dataViews.create(dataViewSpec);
      return {
        list: dataViewList || [],
        loaded: createdAdHocDataView,
        stateVal: createdAdHocDataView.id,
        stateValFound: true
      };
    }
    // reassign fetchId in case of persisted data view spec provided
    fetchId = dataViewSpec.id;
  }
  let fetchedDataView = null;
  // try to fetch adhoc data view first
  try {
    fetchedDataView = fetchId ? await dataViews.get(fetchId, false, true) : null;
    if (fetchedDataView && !fetchedDataView.isPersisted()) {
      return {
        list: dataViewList || [],
        loaded: fetchedDataView,
        stateVal: id,
        stateValFound: true
      };
    }
    // Skipping error handling, since 'get' call trying to fetch
    // adhoc data view which only created using Promise.resolve(dataView),
    // Any other error will be handled by the next 'get' call below.
    // eslint-disable-next-line no-empty
  } catch (e) {}
  let defaultDataView = null;
  if (!fetchedDataView) {
    try {
      defaultDataView = await dataViews.getDefaultDataView({
        displayErrors: false,
        refreshFields: true
      });
    } catch (e) {
      //
    }
  }

  // fetch persisted data view
  return {
    list: dataViewList || [],
    // we can be certain that the data view exists due to an earlier hasData check
    loaded: fetchedDataView || defaultDataView,
    stateVal: fetchId,
    stateValFound: Boolean(fetchId) && Boolean(fetchedDataView)
  };
}

/**
 * Check if the given data view is valid, provide a fallback if it doesn't exist
 * And message the user in this case with toast notifications
 */
function resolveDataView(ip, savedSearch, toastNotifications, isTextBasedQuery) {
  const {
    loaded: loadedDataView,
    stateVal,
    stateValFound
  } = ip;
  const ownDataView = savedSearch === null || savedSearch === void 0 ? void 0 : savedSearch.searchSource.getField('index');
  if (ownDataView && !stateVal) {
    // the given saved search has its own data view, and no data view was specified in the URL
    return ownDataView;
  }

  // no warnings for text based mode
  if (stateVal && !stateValFound && !Boolean(isTextBasedQuery)) {
    const warningTitle = _i18n.i18n.translate('discover.valueIsNotConfiguredDataViewIDWarningTitle', {
      defaultMessage: '{stateVal} is not a configured data view ID',
      values: {
        stateVal: `"${stateVal}"`
      }
    });
    if (ownDataView) {
      // the given data view in the URL was not found, but the saved search has its own data view
      toastNotifications.addWarning({
        title: warningTitle,
        text: _i18n.i18n.translate('discover.showingSavedDataViewWarningDescription', {
          defaultMessage: 'Showing the saved data view: "{ownDataViewTitle}" ({ownDataViewId})',
          values: {
            ownDataViewTitle: ownDataView.getIndexPattern(),
            ownDataViewId: ownDataView.id
          }
        }),
        'data-test-subj': 'dscDataViewNotFoundShowSavedWarning'
      });
      return ownDataView;
    }
    toastNotifications.addWarning({
      title: warningTitle,
      text: _i18n.i18n.translate('discover.showingDefaultDataViewWarningDescription', {
        defaultMessage: 'Showing the default data view: "{loadedDataViewTitle}" ({loadedDataViewId})',
        values: {
          loadedDataViewTitle: loadedDataView.getIndexPattern(),
          loadedDataViewId: loadedDataView.id
        }
      }),
      'data-test-subj': 'dscDataViewNotFoundShowDefaultWarning'
    });
  }
  return loadedDataView;
}
const loadAndResolveDataView = async ({
  id,
  dataViewSpec,
  savedSearch,
  isTextBasedQuery
}, {
  internalStateContainer,
  services
}) => {
  const {
    adHocDataViews,
    savedDataViews
  } = internalStateContainer.getState();
  const adHocDataView = adHocDataViews.find(dataView => dataView.id === id);
  if (adHocDataView) return {
    fallback: false,
    dataView: adHocDataView
  };
  const nextDataViewData = await loadDataView({
    services,
    id,
    dataViewSpec,
    dataViewList: savedDataViews
  });
  const nextDataView = resolveDataView(nextDataViewData, savedSearch, services.toastNotifications, isTextBasedQuery);
  return {
    fallback: !nextDataViewData.stateValFound,
    dataView: nextDataView
  };
};
exports.loadAndResolveDataView = loadAndResolveDataView;