"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useManualRules = exports.ManualRulesContainer = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _reactMagneticDi = require("react-magnetic-di");
var _modalDialog = require("@atlaskit/modal-dialog");
var _main = _interopRequireDefault(require("./manual-triggers-form/main"));
var _services = require("./services");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t3 in e) "default" !== _t3 && {}.hasOwnProperty.call(e, _t3) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t3)) && (i.get || i.set) ? o(f, _t3, i) : f[_t3] = e[_t3]); return f; })(e, t); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/**
 * React hook that implements the fetch and invoke actions for manual triggers.
 * Can be used standalone or in the HOC provided below.
 * @param site - The site to filter on. We map this to just a cloudId to resolve the manual rules API path
 * @param query - Query object containing filter props (container, object(s))
 */
var useManualRules = exports.useManualRules = function useManualRules(site, query) {
  var _useState = (0, _react.useState)(false),
    _useState2 = (0, _slicedToArray2.default)(_useState, 2),
    initialised = _useState2[0],
    setInitialised = _useState2[1];
  var _useState3 = (0, _react.useState)(null),
    _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
    error = _useState4[0],
    setError = _useState4[1];
  var _useState5 = (0, _react.useState)([]),
    _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
    rules = _useState6[0],
    setRules = _useState6[1];
  var transformRules = function transformRules(ruleResponse) {
    var rulesUnsorted = Object.values(ruleResponse);
    return rulesUnsorted.sort(function (rule1, rule2) {
      return rule1.name.localeCompare(rule2.name);
    });
  };
  var triggerFetch = /*#__PURE__*/function () {
    var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
      var fetchedRules, _t;
      return _regenerator.default.wrap(function (_context) {
        while (1) switch (_context.prev = _context.next) {
          case 0:
            setInitialised(false);
            _context.prev = 1;
            _context.next = 2;
            return (0, _services.searchManuallyTriggeredRules)(site, query);
          case 2:
            fetchedRules = _context.sent;
            setError(null);
            setRules(transformRules(fetchedRules));
            _context.next = 4;
            break;
          case 3:
            _context.prev = 3;
            _t = _context["catch"](1);
            setError(_t);
            setRules([]);
          case 4:
            _context.prev = 4;
            setInitialised(true);
            return _context.finish(4);
          case 5:
          case "end":
            return _context.stop();
        }
      }, _callee, null, [[1, 3, 4, 5]]);
    }));
    return function triggerFetch() {
      return _ref.apply(this, arguments);
    };
  }();
  return [triggerFetch, initialised, error, rules];
};
/**
 *
 * Container HOC that implements the above hook and behaviours.
 *
 * This HOC uses rendered props to allow the use of any render instructions
 * for manual rules, while still maintaining the behaviour of invoking rules.
 *
 * The HOC also appends a dialog that is displayed when the {@code invokeRuleOrShowDialog}
 * prop is called, if the underlying rule has user inputs.
 *
 * The component exposes the "invokingRuleId" property to the child hierarchy,
 * because the children might care about the invocation state. It does not expose
 * the "selected" state, or any information about the dialog, as the children
 * should not care about this, only how to trigger invocation and understand
 * the invocation lifecycle.
 *
 * @param props - cloudId, projectId, children
 */
var ManualRulesContainer = exports.ManualRulesContainer = function ManualRulesContainer(props) {
  var site = props.site,
    query = props.query,
    children = props.children,
    onInputsModalOpened = props.onInputsModalOpened,
    onInputsModalClosed = props.onInputsModalClosed,
    onRuleInvocationLifecycleStarted = props.onRuleInvocationLifecycleStarted,
    onRuleInvocationSuccess = props.onRuleInvocationSuccess,
    onRuleInvocationFailure = props.onRuleInvocationFailure,
    onRuleInvocationLifecycleDone = props.onRuleInvocationLifecycleDone;
  // Initial data loading state
  var _useManualRules = useManualRules(site, query),
    _useManualRules2 = (0, _slicedToArray2.default)(_useManualRules, 4),
    triggerFetch = _useManualRules2[0],
    initialised = _useManualRules2[1],
    error = _useManualRules2[2],
    rules = _useManualRules2[3];
  // We store a rule in state here if and only if a rule has user inputs, and thus
  // we need to preserve state while the input dialog is open.
  var _useState7 = (0, _react.useState)(null),
    _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
    selectedRule = _useState8[0],
    setSelectedRule = _useState8[1];
  var clearSelectedRule = function clearSelectedRule() {
    setSelectedRule(null);
  };
  // Value set when a rule is invoking, either from the dialog or without dialog
  var _useState9 = (0, _react.useState)(null),
    _useState0 = (0, _slicedToArray2.default)(_useState9, 2),
    invokingRuleId = _useState0[0],
    setInvokingRuleId = _useState0[1];

  // Memoized projection of rules by id
  var rulesById = (0, _react.useMemo)(function () {
    return rules.reduce(function (acc, rule) {
      return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2.default)({}, rule.id, rule));
    }, {});
  }, [rules]);
  var getRule = function getRule(id) {
    return rulesById[id];
  };
  var ruleHasInputs = function ruleHasInputs(rule) {
    var _rule$userInputPrompt;
    return (rule === null || rule === void 0 || (_rule$userInputPrompt = rule.userInputPrompts) === null || _rule$userInputPrompt === void 0 ? void 0 : _rule$userInputPrompt.length) > 0;
  };
  var getFailedObjects = function getFailedObjects(response) {
    return Object.keys(response).filter(function (object) {
      return response[object] !== 'SUCCESS';
    });
  };
  var getSuccessfulObjects = function getSuccessfulObjects(response) {
    return Object.keys(response).filter(function (object) {
      return response[object] === 'SUCCESS';
    });
  };
  var handleInvocationFailure = function handleInvocationFailure(ruleId, successfulObjects, failedObjects) {
    if (onRuleInvocationFailure) {
      onRuleInvocationFailure(ruleId, successfulObjects, failedObjects);
    }
  };
  var invokeRule = /*#__PURE__*/function () {
    var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(ruleId, objects, userInputs) {
      var rule, response, failedObjects, successfulObjects, _t2;
      return _regenerator.default.wrap(function (_context2) {
        while (1) switch (_context2.prev = _context2.next) {
          case 0:
            rule = getRule(ruleId);
            if (!rule) {
              _context2.next = 5;
              break;
            }
            setInvokingRuleId(ruleId);
            _context2.prev = 1;
            if (onRuleInvocationLifecycleStarted) {
              onRuleInvocationLifecycleStarted(ruleId, objects, userInputs);
            }
            _context2.next = 2;
            return (0, _services.invokeManuallyTriggeredRule)(site, ruleId, objects, userInputs);
          case 2:
            response = _context2.sent;
            failedObjects = getFailedObjects(response);
            setInvokingRuleId(null);
            if (failedObjects.length === 0) {
              if (onRuleInvocationSuccess) {
                onRuleInvocationSuccess(ruleId, objects);
              }
            } else {
              successfulObjects = getSuccessfulObjects(response);
              handleInvocationFailure(ruleId, successfulObjects, failedObjects);
            }
            _context2.next = 4;
            break;
          case 3:
            _context2.prev = 3;
            _t2 = _context2["catch"](1);
            handleInvocationFailure(ruleId, [], objects);
            setInvokingRuleId(null);
          case 4:
            _context2.next = 6;
            break;
          case 5:
            handleInvocationFailure(ruleId, [], objects);
          case 6:
            clearSelectedRule();
            if (onRuleInvocationLifecycleDone) {
              onRuleInvocationLifecycleDone(ruleId, objects);
            }
          case 7:
          case "end":
            return _context2.stop();
        }
      }, _callee2, null, [[1, 3]]);
    }));
    return function invokeRule(_x, _x2, _x3) {
      return _ref2.apply(this, arguments);
    };
  }();
  var invokeRuleOrShowDialog = function invokeRuleOrShowDialog(ruleId, objects) {
    var rule = getRule(ruleId);
    if (!rule) {
      return handleInvocationFailure(ruleId, [], objects);
    }
    if (ruleHasInputs(rule)) {
      setSelectedRule({
        rule: rule,
        objects: objects
      });
    } else {
      invokeRule(ruleId, objects);
    }
  };
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children({
    triggerFetch: triggerFetch,
    initialised: initialised,
    error: error,
    rules: rules,
    invokingRuleId: invokingRuleId,
    invokeRuleOrShowDialog: invokeRuleOrShowDialog
  }), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTransition, null, selectedRule && /*#__PURE__*/_react.default.createElement(_main.default, {
    onInputsModalOpened: onInputsModalOpened,
    onInputsModalClosed: onInputsModalClosed,
    clearSelectedRule: clearSelectedRule,
    selectedRule: selectedRule,
    invokeRule: invokeRule
  })));
};