"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.popoverWidth = exports.getNodeHeight = exports.getCytoscapeOptions = exports.getCytoscapeDivStyle = exports.getAnimationOptions = void 0;
var _apm = require("../../../../common/es_fields/apm");
var _service_health_status = require("../../../../common/service_health_status");
var _use_fetcher = require("../../../hooks/use_fetcher");
var _icons = require("./icons");
/*
 * 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; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

const popoverWidth = 350;
exports.popoverWidth = popoverWidth;
function getServiceAnomalyStats(el) {
  const serviceAnomalyStats = el.data('serviceAnomalyStats');
  return serviceAnomalyStats;
}
function getBorderColorFn(theme) {
  return el => {
    const hasAnomalyDetectionJob = el.data('serviceAnomalyStats') !== undefined;
    const anomalyStats = getServiceAnomalyStats(el);
    if (hasAnomalyDetectionJob) {
      var _anomalyStats$healthS;
      return (0, _service_health_status.getServiceHealthStatusColor)(theme, (_anomalyStats$healthS = anomalyStats === null || anomalyStats === void 0 ? void 0 : anomalyStats.healthStatus) !== null && _anomalyStats$healthS !== void 0 ? _anomalyStats$healthS : _service_health_status.ServiceHealthStatus.unknown);
    }
    if (el.hasClass('primary') || el.selected()) {
      return theme.eui.euiColorPrimary;
    }
    return theme.eui.euiColorMediumShade;
  };
}
const getBorderStyle = el => {
  var _getServiceAnomalySta;
  const status = (_getServiceAnomalySta = getServiceAnomalyStats(el)) === null || _getServiceAnomalySta === void 0 ? void 0 : _getServiceAnomalySta.healthStatus;
  if (status === _service_health_status.ServiceHealthStatus.critical) {
    return 'double';
  } else {
    return 'solid';
  }
};
function getBorderWidth(el) {
  var _getServiceAnomalySta2;
  const status = (_getServiceAnomalySta2 = getServiceAnomalyStats(el)) === null || _getServiceAnomalySta2 === void 0 ? void 0 : _getServiceAnomalySta2.healthStatus;
  if (status === _service_health_status.ServiceHealthStatus.warning) {
    return 4;
  } else if (status === _service_health_status.ServiceHealthStatus.critical) {
    return 8;
  } else {
    return 4;
  }
}

// IE 11 does not properly load some SVGs or draw certain shapes. This causes
// a runtime error and the map fails work at all. We would prefer to do some
// kind of feature detection rather than browser detection, but some of these
// limitations are not well documented for older browsers.
//
// This method of detecting IE is from a Stack Overflow answer:
// https://stackoverflow.com/a/21825207
//
// @ts-expect-error `documentMode` is not recognized as a valid property of `document`.
const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
const getAnimationOptions = theme => ({
  duration: parseInt(theme.eui.euiAnimSpeedNormal, 10),
  // @ts-expect-error The cubic-bezier options here are not recognized by the cytoscape types
  easing: theme.eui.euiAnimSlightBounce
});
exports.getAnimationOptions = getAnimationOptions;
const zIndexNode = 200;
const zIndexEdge = 100;
const zIndexEdgeHighlight = 110;
const zIndexEdgeHover = 120;
const getNodeHeight = theme => parseInt(theme.eui.euiSizeXXL, 10);
exports.getNodeHeight = getNodeHeight;
function isService(el) {
  return el.data(_apm.SERVICE_NAME) !== undefined;
}
const getStyle = (theme, isTraceExplorerEnabled) => {
  const lineColor = theme.eui.euiColorMediumShade;
  return [{
    selector: 'core',
    // @ts-expect-error DefinitelyTyped does not recognize 'active-bg-opacity'
    style: {
      'active-bg-opacity': 0
    }
  }, {
    selector: 'node',
    style: {
      'background-color': theme.eui.euiColorGhost,
      // The DefinitelyTyped definitions don't specify that a function can be
      // used here.
      'background-image': el => (0, _icons.iconForNode)(el),
      'background-height': el => isService(el) ? '60%' : '40%',
      'background-width': el => isService(el) ? '60%' : '40%',
      'border-color': getBorderColorFn(theme),
      'border-style': getBorderStyle,
      'border-width': getBorderWidth,
      color: el => el.hasClass('primary') || el.selected() ? theme.eui.euiColorPrimaryText : theme.eui.euiTextColor,
      // theme.euiFontFamily doesn't work here for some reason, so we're just
      // specifying a subset of the fonts for the label text.
      'font-family': 'Inter UI, Segoe UI, Helvetica, Arial, sans-serif',
      'font-size': theme.eui.euiFontSizeS,
      ghost: 'yes',
      'ghost-offset-x': 0,
      'ghost-offset-y': 2,
      'ghost-opacity': 0.15,
      height: getNodeHeight(theme),
      label: el => isService(el) ? el.data(_apm.SERVICE_NAME) : el.data('label') || el.data(_apm.SPAN_DESTINATION_SERVICE_RESOURCE),
      'min-zoomed-font-size': parseInt(theme.eui.euiSizeS, 10),
      'overlay-opacity': 0,
      shape: el => isService(el) ? isIE11 ? 'rectangle' : 'ellipse' : 'diamond',
      'text-background-color': theme.eui.euiColorPrimary,
      'text-background-opacity': el => el.hasClass('primary') || el.selected() ? 0.1 : 0,
      'text-background-padding': theme.eui.euiSizeXS,
      'text-background-shape': 'roundrectangle',
      'text-margin-y': parseInt(theme.eui.euiSizeS, 10),
      'text-max-width': '200px',
      'text-valign': 'bottom',
      'text-wrap': 'ellipsis',
      width: theme.eui.euiSizeXXL,
      'z-index': zIndexNode
    }
  }, {
    selector: 'edge',
    style: {
      'curve-style': 'unbundled-bezier',
      'line-color': lineColor,
      'overlay-opacity': 0,
      'target-arrow-color': lineColor,
      'target-arrow-shape': isIE11 ? 'none' : 'triangle',
      // The DefinitelyTyped definitions don't specify this property since it's
      // fairly new.
      //
      // @ts-expect-error
      'target-distance-from-node': isIE11 ? undefined : theme.eui.euiSizeXS,
      width: 1,
      'source-arrow-shape': 'none',
      'z-index': zIndexEdge
    }
  }, {
    selector: 'edge[bidirectional]',
    style: {
      'source-arrow-shape': isIE11 ? 'none' : 'triangle',
      'source-arrow-color': lineColor,
      'target-arrow-shape': isIE11 ? 'none' : 'triangle',
      // @ts-expect-error
      'source-distance-from-node': isIE11 ? undefined : parseInt(theme.eui.euiSizeXS, 10),
      'target-distance-from-node': isIE11 ? undefined : parseInt(theme.eui.euiSizeXS, 10)
    }
  }, {
    selector: 'edge[isInverseEdge]',
    // @ts-expect-error DefinitelyTyped says visibility is "none" but it's
    // actually "hidden"
    style: {
      visibility: 'hidden'
    }
  }, {
    selector: 'edge.nodeHover',
    style: {
      width: 4,
      'z-index': zIndexEdgeHover,
      'line-color': theme.eui.euiColorDarkShade,
      'source-arrow-color': theme.eui.euiColorDarkShade,
      'target-arrow-color': theme.eui.euiColorDarkShade
    }
  }, ...(isTraceExplorerEnabled ? [{
    selector: 'edge.hover',
    style: {
      width: 4,
      'z-index': zIndexEdgeHover,
      'line-color': theme.eui.euiColorDarkShade,
      'source-arrow-color': theme.eui.euiColorDarkShade,
      'target-arrow-color': theme.eui.euiColorDarkShade
    }
  }] : []), {
    selector: 'node.hover',
    style: {
      'border-width': getBorderWidth
    }
  }, {
    selector: 'edge.highlight',
    style: {
      width: 4,
      'line-color': theme.eui.euiColorPrimary,
      'source-arrow-color': theme.eui.euiColorPrimary,
      'target-arrow-color': theme.eui.euiColorPrimary,
      'z-index': zIndexEdgeHighlight
    }
  }];
};

// The CSS styles for the div containing the cytoscape element. Makes a
// background grid of dots.
const getCytoscapeDivStyle = (theme, status) => ({
  background: `linear-gradient(
  90deg,
  ${theme.eui.euiPageBackgroundColor}
    calc(${theme.eui.euiSizeL} - calc(${theme.eui.euiSizeXS} / 2)),
  transparent 1%
)
center,
linear-gradient(
  ${theme.eui.euiPageBackgroundColor}
    calc(${theme.eui.euiSizeL} - calc(${theme.eui.euiSizeXS} / 2)),
  transparent 1%
)
center,
${theme.eui.euiColorLightShade}`,
  backgroundSize: `${theme.eui.euiSizeL} ${theme.eui.euiSizeL}`,
  cursor: `${status === _use_fetcher.FETCH_STATUS.LOADING ? 'wait' : 'grab'}`,
  marginTop: 0
});
exports.getCytoscapeDivStyle = getCytoscapeDivStyle;
const getCytoscapeOptions = (theme, isTraceExplorerEnabled) => ({
  boxSelectionEnabled: false,
  maxZoom: 3,
  minZoom: 0.2,
  style: getStyle(theme, isTraceExplorerEnabled)
});
exports.getCytoscapeOptions = getCytoscapeOptions;