"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.combineDashboardFiltersWithControlGroupFilters = void 0;
exports.startSyncingDashboardControlGroup = startSyncingDashboardControlGroup;
var _lodash = require("lodash");
var _fastDeepEqual = _interopRequireDefault(require("fast-deep-equal"));
var _esQuery = require("@kbn/es-query");
var _operators = require("rxjs/operators");
var _common = require("@kbn/controls-plugin/common");
/*
 * 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.
 */

const distinctUntilDiffCheck = (a, b, diffChecks) => !Object.keys(diffChecks).map(key => (0, _fastDeepEqual.default)(a[key], b[key])).includes(false);
function startSyncingDashboardControlGroup() {
  if (!this.controlGroup) return;
  const isControlGroupInputEqual = () => (0, _common.persistableControlGroupInputIsEqual)(this.controlGroup.getInput(), this.getInput().controlGroupInput);

  // Because dashboard container stores control group state, certain control group changes need to be passed up dashboard container
  const controlGroupDiff = {
    panels: _fastDeepEqual.default,
    controlStyle: _fastDeepEqual.default,
    chainingSystem: _fastDeepEqual.default,
    ignoreParentSettings: _fastDeepEqual.default
  };
  this.integrationSubscriptions.add(this.controlGroup.getInput$().pipe((0, _operators.distinctUntilChanged)((a, b) => distinctUntilDiffCheck(a, b, controlGroupDiff))).subscribe(() => {
    const {
      panels,
      controlStyle,
      chainingSystem,
      ignoreParentSettings
    } = this.controlGroup.getInput();
    if (!isControlGroupInputEqual()) {
      this.dispatch.setControlGroupState({
        panels,
        controlStyle,
        chainingSystem,
        ignoreParentSettings
      });
    }
  }));
  const compareAllFilters = (a, b) => (0, _esQuery.compareFilters)(a !== null && a !== void 0 ? a : [], b !== null && b !== void 0 ? b : [], _esQuery.COMPARE_ALL_OPTIONS);
  const dashboardRefetchDiff = {
    filters: (a, b) => compareAllFilters(a, b),
    timeRange: _fastDeepEqual.default,
    query: _fastDeepEqual.default,
    viewMode: _fastDeepEqual.default
  };

  // pass down any pieces of input needed to refetch or force refetch data for the controls
  this.integrationSubscriptions.add(this.getInput$().pipe((0, _operators.distinctUntilChanged)((a, b) => distinctUntilDiffCheck(a, b, dashboardRefetchDiff))).subscribe(() => {
    const newInput = {};
    Object.keys(dashboardRefetchDiff).forEach(key => {
      var _dashboardRefetchDiff;
      if (!((_dashboardRefetchDiff = dashboardRefetchDiff[key]) !== null && _dashboardRefetchDiff !== void 0 && _dashboardRefetchDiff.call(dashboardRefetchDiff, this.getInput()[key], this.controlGroup.getInput()[key]))) {
        newInput[key] = this.getInput()[key];
      }
    });
    if (Object.keys(newInput).length > 0) {
      this.controlGroup.updateInput(newInput);
    }
  }));

  // when control group outputs filters, force a refresh!
  this.integrationSubscriptions.add(this.controlGroup.getOutput$().pipe((0, _operators.distinctUntilChanged)(({
    filters: filtersA
  }, {
    filters: filtersB
  }) => compareAllFilters(filtersA, filtersB)), (0, _operators.skip)(1) // skip first filter output because it will have been applied in initialize
  ).subscribe(() => this.forceRefresh(false)) // we should not reload the control group when the control group output changes - otherwise, performance is severely impacted
  );

  this.integrationSubscriptions.add(this.controlGroup.getOutput$().pipe((0, _operators.distinctUntilChanged)(({
    timeslice: timesliceA
  }, {
    timeslice: timesliceB
  }) => (0, _lodash.isEqual)(timesliceA, timesliceB))).subscribe(({
    timeslice
  }) => {
    if (!(0, _lodash.isEqual)(timeslice, this.getInput().timeslice)) {
      this.dispatch.setTimeslice(timeslice);
    }
  }));

  // the Control Group needs to know when any dashboard children are loading in order to know when to move on to the next time slice when playing.
  this.integrationSubscriptions.add(this.getAnyChildOutputChange$().subscribe(() => {
    if (!this.controlGroup) {
      return;
    }
    for (const child of Object.values(this.children)) {
      const isLoading = child.getOutput().loading;
      if (isLoading) {
        this.controlGroup.anyControlOutputConsumerLoading$.next(true);
        return;
      }
    }
    this.controlGroup.anyControlOutputConsumerLoading$.next(false);
  }));
}
const combineDashboardFiltersWithControlGroupFilters = (dashboardFilters, controlGroup) => {
  var _controlGroup$getOutp;
  return [...dashboardFilters, ...((_controlGroup$getOutp = controlGroup.getOutput().filters) !== null && _controlGroup$getOutp !== void 0 ? _controlGroup$getOutp : [])];
};
exports.combineDashboardFiltersWithControlGroupFilters = combineDashboardFiltersWithControlGroupFilters;