"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.AgentLogsUrlStateHelper = exports.AgentLogsUI = void 0;
var _url = _interopRequireDefault(require("url"));
var _querystring = require("querystring");
var _react = _interopRequireWildcard(require("react"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _rison = require("@kbn/rison");
var _eui = require("@elastic/eui");
var _useMeasure = _interopRequireDefault(require("react-use/lib/useMeasure"));
var _i18nReact = require("@kbn/i18n-react");
var _esQuery = require("@kbn/es-query");
var _gte = _interopRequireDefault(require("semver/functions/gte"));
var _coerce = _interopRequireDefault(require("semver/functions/coerce"));
var _public = require("@kbn/kibana-utils-plugin/public");
var _public2 = require("@kbn/kibana-react-plugin/public");
var _public3 = require("@kbn/logs-shared-plugin/public");
var _hooks = require("../../../../../hooks");
var _constants = require("./constants");
var _filter_dataset = require("./filter_dataset");
var _filter_log_level = require("./filter_log_level");
var _query_bar = require("./query_bar");
var _build_query = require("./build_query");
var _select_log_level = require("./select_log_level");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/*
 * 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 WrapperFlexGroup = (0, _styledComponents.default)(_eui.EuiFlexGroup)`
  height: 100%;
`;
const DatePickerFlexItem = (0, _styledComponents.default)(_eui.EuiFlexItem)`
  max-width: 312px;
`;
const LOG_VIEW_SETTINGS = {
  type: 'log-view-reference',
  logViewId: 'default'
};
const AgentLogsUrlStateHelper = (0, _public.createStateContainerReactHelpers)();
exports.AgentLogsUrlStateHelper = AgentLogsUrlStateHelper;
const AgentPolicyLogsNotEnabledCallout = ({
  agentPolicy
}) => {
  const {
    getHref
  } = (0, _hooks.useLink)();
  return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiCallOut, {
    size: "m",
    color: "primary",
    iconType: "iInCircle",
    title: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
      id: "xpack.fleet.agentLogs.logDisabledCallOutTitle",
      defaultMessage: "Log collection is disabled"
    })
  }, agentPolicy.is_managed ? null : /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
    id: "xpack.fleet.agentLogs.logDisabledCallOutDescription",
    defaultMessage: "Update the agent's policy {settingsLink} to enable logs collection.",
    values: {
      settingsLink: /*#__PURE__*/_react.default.createElement(_eui.EuiLink, {
        href: getHref('policy_details', {
          policyId: agentPolicy.id,
          tabId: 'settings'
        })
      }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
        id: "xpack.fleet.agentLogs.settingsLink",
        defaultMessage: "settings"
      }))
    }
  })));
};
const AgentLogsUI = /*#__PURE__*/(0, _react.memo)(({
  agent,
  agentPolicy,
  state
}) => {
  var _agent$local_metadata, _agent$local_metadata2, _agent$local_metadata3, _agentPolicy$monitori;
  const {
    data,
    application,
    http
  } = (0, _hooks.useStartServices)();
  const {
    update: updateState
  } = AgentLogsUrlStateHelper.useTransitions();

  // Util to convert date expressions (returned by datepicker) to timestamps (used by LogStream)
  const getDateRangeTimestamps = (0, _react.useCallback)(timeRange => {
    const {
      min,
      max
    } = data.query.timefilter.timefilter.calculateBounds(timeRange);
    return min && max ? {
      start: min.valueOf(),
      end: max.valueOf()
    } : undefined;
  }, [data.query.timefilter.timefilter]);
  const tryUpdateDateRange = (0, _react.useCallback)(timeRange => {
    const timestamps = getDateRangeTimestamps(timeRange);
    if (timestamps) {
      updateState({
        start: timeRange.from,
        end: timeRange.to
      });
    }
  }, [getDateRangeTimestamps, updateState]);
  const [dateRangeTimestamps, setDateRangeTimestamps] = (0, _react.useState)(getDateRangeTimestamps({
    from: state.start,
    to: state.end
  }) || getDateRangeTimestamps({
    from: _constants.DEFAULT_DATE_RANGE.start,
    to: _constants.DEFAULT_DATE_RANGE.end
  }));

  // Attempts to parse for timestamps when start/end date expressions change
  // If invalid date expressions, set expressions back to default
  // Otherwise set the new timestamps
  (0, _react.useEffect)(() => {
    const timestampsFromDateRange = getDateRangeTimestamps({
      from: state.start,
      to: state.end
    });
    if (!timestampsFromDateRange) {
      tryUpdateDateRange({
        from: _constants.DEFAULT_DATE_RANGE.start,
        to: _constants.DEFAULT_DATE_RANGE.end
      });
    } else {
      setDateRangeTimestamps(timestampsFromDateRange);
    }
  }, [state.start, state.end, getDateRangeTimestamps, tryUpdateDateRange]);

  // Query validation helper
  const isQueryValid = (0, _react.useCallback)(testQuery => {
    try {
      (0, _esQuery.fromKueryExpression)(testQuery);
      return true;
    } catch (err) {
      return false;
    }
  }, []);

  // User query state
  const [draftQuery, setDraftQuery] = (0, _react.useState)(state.query);
  const [isDraftQueryValid, setIsDraftQueryValid] = (0, _react.useState)(isQueryValid(state.query));
  const onUpdateDraftQuery = (0, _react.useCallback)((newDraftQuery, runQuery) => {
    setDraftQuery(newDraftQuery);
    if (isQueryValid(newDraftQuery)) {
      setIsDraftQueryValid(true);
      if (runQuery) {
        updateState({
          query: newDraftQuery
        });
      }
    } else {
      setIsDraftQueryValid(false);
    }
  }, [isQueryValid, updateState]);

  // Build final log stream query from agent id, datasets, log levels, and user input
  const logStreamQuery = (0, _react.useMemo)(() => (0, _build_query.buildQuery)({
    agentId: agent.id,
    datasets: state.datasets,
    logLevels: state.logLevels,
    userQuery: state.query
  }), [agent.id, state.datasets, state.logLevels, state.query]);

  // Generate URL to pass page state to Logs UI
  const viewInLogsUrl = (0, _react.useMemo)(() => http.basePath.prepend(_url.default.format({
    pathname: '/app/logs/stream',
    search: (0, _querystring.stringify)({
      logPosition: (0, _rison.encode)({
        start: state.start,
        end: state.end,
        streamLive: false
      }),
      logFilter: (0, _rison.encode)({
        expression: logStreamQuery,
        kind: 'kuery'
      })
    })
  })), [http.basePath, state.start, state.end, logStreamQuery]);
  const agentVersion = (_agent$local_metadata = agent.local_metadata) === null || _agent$local_metadata === void 0 ? void 0 : (_agent$local_metadata2 = _agent$local_metadata.elastic) === null || _agent$local_metadata2 === void 0 ? void 0 : (_agent$local_metadata3 = _agent$local_metadata2.agent) === null || _agent$local_metadata3 === void 0 ? void 0 : _agent$local_metadata3.version;
  const isLogFeatureAvailable = (0, _react.useMemo)(() => {
    var _semverCoerce;
    if (!agentVersion) {
      return false;
    }
    const agentVersionWithPrerelease = (_semverCoerce = (0, _coerce.default)(agentVersion)) === null || _semverCoerce === void 0 ? void 0 : _semverCoerce.version;
    if (!agentVersionWithPrerelease) {
      return false;
    }
    return (0, _gte.default)(agentVersionWithPrerelease, '7.11.0');
  }, [agentVersion]);

  // Set absolute height on logs component (needed to render correctly in Safari)
  // based on available height, or 600px, whichever is greater
  const [logsPanelRef, {
    height: measuredlogPanelHeight
  }] = (0, _useMeasure.default)();
  const logPanelHeight = (0, _react.useMemo)(() => Math.max(measuredlogPanelHeight, 600), [measuredlogPanelHeight]);
  if (!isLogFeatureAvailable) {
    return /*#__PURE__*/_react.default.createElement(_eui.EuiCallOut, {
      size: "m",
      color: "warning",
      title: /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
        id: "xpack.fleet.agentLogs.oldAgentWarningTitle",
        defaultMessage: "The Logs view requires Elastic Agent 7.11 or higher. To upgrade an agent, go to the Actions menu, or {downloadLink} a newer version.",
        values: {
          downloadLink: /*#__PURE__*/_react.default.createElement(_eui.EuiLink, {
            href: "https://ela.st/download-elastic-agent",
            external: true,
            target: "_blank"
          }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
            id: "xpack.fleet.agentLogs.downloadLink",
            defaultMessage: "download"
          }))
        }
      })
    });
  }
  return /*#__PURE__*/_react.default.createElement(WrapperFlexGroup, {
    direction: "column",
    gutterSize: "m"
  }, agentPolicy && !((_agentPolicy$monitori = agentPolicy.monitoring_enabled) !== null && _agentPolicy$monitori !== void 0 && _agentPolicy$monitori.includes('logs')) && /*#__PURE__*/_react.default.createElement(AgentPolicyLogsNotEnabledCallout, {
    agentPolicy: agentPolicy
  }), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
    grow: false
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
    gutterSize: "m"
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_query_bar.LogQueryBar, {
    query: draftQuery,
    onUpdateQuery: onUpdateDraftQuery,
    isQueryValid: isDraftQueryValid
  })), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
    grow: false
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiFilterGroup, null, /*#__PURE__*/_react.default.createElement(_filter_dataset.DatasetFilter, {
    selectedDatasets: state.datasets,
    onToggleDataset: dataset => {
      const currentDatasets = [...state.datasets];
      const datasetPosition = currentDatasets.indexOf(dataset);
      if (datasetPosition >= 0) {
        currentDatasets.splice(datasetPosition, 1);
        updateState({
          datasets: currentDatasets
        });
      } else {
        updateState({
          datasets: [...state.datasets, dataset]
        });
      }
    }
  }), /*#__PURE__*/_react.default.createElement(_filter_log_level.LogLevelFilter, {
    selectedLevels: state.logLevels,
    onToggleLevel: level => {
      const currentLevels = [...state.logLevels];
      const levelPosition = currentLevels.indexOf(level);
      if (levelPosition >= 0) {
        currentLevels.splice(levelPosition, 1);
        updateState({
          logLevels: currentLevels
        });
      } else {
        updateState({
          logLevels: [...state.logLevels, level]
        });
      }
    }
  }))), /*#__PURE__*/_react.default.createElement(DatePickerFlexItem, {
    grow: false
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiSuperDatePicker, {
    showUpdateButton: false,
    start: state.start,
    end: state.end,
    onTimeChange: ({
      start,
      end
    }) => {
      tryUpdateDateRange({
        from: start,
        to: end
      });
    }
  })), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
    grow: false
  }, /*#__PURE__*/_react.default.createElement(_public2.RedirectAppLinks, {
    application: application
  }, /*#__PURE__*/_react.default.createElement(_eui.EuiButtonEmpty, {
    href: viewInLogsUrl,
    iconType: "popout",
    flush: "both"
  }, /*#__PURE__*/_react.default.createElement(_i18nReact.FormattedMessage, {
    id: "xpack.fleet.agentLogs.openInLogsUiLinkText",
    defaultMessage: "Open in Logs"
  })))))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiPanel, {
    paddingSize: "none",
    panelRef: logsPanelRef,
    grow: false
  }, /*#__PURE__*/_react.default.createElement(_public3.LogStream, {
    logView: LOG_VIEW_SETTINGS,
    height: logPanelHeight,
    startTimestamp: dateRangeTimestamps.start,
    endTimestamp: dateRangeTimestamps.end,
    query: logStreamQuery
  }))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
    grow: false
  }, /*#__PURE__*/_react.default.createElement(_select_log_level.SelectLogLevel, {
    agent: agent
  })));
});
exports.AgentLogsUI = AgentLogsUI;