var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
            t[p[i]] = s[p[i]];
    return t;
};
import * as _ from 'lodash';
import React from 'react';
import { getComponentDisplayName } from '../util/hocUtil';
export const HeapIgnore = props => {
    // The only purpose of HeapIgnore is to tell the us which props apply to the subtree when we're
    // traversing, so we just need to render it's children here.
    return props.children;
};
// Convenience component for only ignoring target text.
export const HeapIgnoreTargetText = props => {
    return (React.createElement(HeapIgnore, { allowInteraction: true, allowInnerHierarchy: true, allowAllProps: true, allowTargetText: false }, props.children));
};
export const withHeapIgnore = (IgnoredComponent, heapIgnoreConfig) => {
    class WithHeapIgnore extends React.Component {
        render() {
            const _a = this.props, { forwardedRef } = _a, rest = __rest(_a, ["forwardedRef"]);
            return (React.createElement(HeapIgnore, Object.assign({}, heapIgnoreConfig),
                React.createElement(IgnoredComponent, Object.assign({ ref: forwardedRef }, rest), this.props.children)));
        }
    }
    WithHeapIgnore.displayName = `withHeapIgnore(${getComponentDisplayName(IgnoredComponent)})`;
    return React.forwardRef((props, ref) => {
        return React.createElement(WithHeapIgnore, Object.assign({}, props, { forwardedRef: ref }));
    });
};
export const BASE_HEAP_IGNORE_PROPS = {
    allowInteraction: false,
    allowInnerHierarchy: false,
    allowAllProps: false,
    // :TODO: (jmtaber129): Implement 'ignoreSpecificProps'.
    allowTargetText: false,
};
export const getNextHeapIgnoreProps = (currProps, element) => {
    if (element.elementName !== 'HeapIgnore') {
        return currProps;
    }
    // Normally, we'd want to check for props on a 'stateNode' that may or may not be present.
    // However, because we know that the HeapIgnore components are functional components, we already
    // know there is not 'stateNode'.
    const specifiedHeapIgnoreProps = _.pick(element.fiberNode.memoizedProps, Object.keys(BASE_HEAP_IGNORE_PROPS));
    let actualHeapIgnoreProps = {};
    actualHeapIgnoreProps = _.merge({}, BASE_HEAP_IGNORE_PROPS, specifiedHeapIgnoreProps);
    // New HeapIgnore props for the subtree should be at least as restrictive as it already was.
    return _.mapValues(currProps, (value, key) => {
        return value && actualHeapIgnoreProps[key];
    });
};
