"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Configuration_1 = require("./Configuration");
exports.LifecycleHelper = (Cloudwise, Logger) => {
    return {
        attachLifycycleListener: function (lifecycleComponent) {
            let componentDidMountOrig;
            if (lifecycleComponent.componentDidMount !== undefined) {
                componentDidMountOrig = lifecycleComponent.componentDidMount.bind(lifecycleComponent);
            }
            lifecycleComponent.componentDidMount = () => {
                this._componentDidMountCloudwise(lifecycleComponent, componentDidMountOrig);
            };
            let componentDidUpdateOrig;
            if (lifecycleComponent.componentDidUpdate !== undefined) {
                componentDidUpdateOrig = lifecycleComponent.componentDidUpdate.bind(lifecycleComponent);
            }
            lifecycleComponent.componentDidUpdate = (prevProps, prevState, snapshot) => {
                this._componentDidUpdateCloudwise(lifecycleComponent, prevProps, prevState, snapshot, componentDidUpdateOrig);
            };
            const renderOrig = lifecycleComponent.render.bind(lifecycleComponent);
            lifecycleComponent.render = () => {
                return this._renderCloudwise(lifecycleComponent, renderOrig);
            };
            let componentWillUnmountOrig;
            if (lifecycleComponent.componentWillUnmount !== undefined) {
                componentWillUnmountOrig = lifecycleComponent.componentWillUnmount.bind(lifecycleComponent);
            }
            lifecycleComponent.componentWillUnmount = () => {
                this._componentWillUnmountCloudwise(lifecycleComponent, componentWillUnmountOrig);
            };
        },
        _componentDidMountCloudwise: function (lifecycleComponent, componentDidMountOrig) {
            if (componentDidMountOrig !== undefined) {
                componentDidMountOrig();
            }
            lifecycleComponent._cloudwiseMounted = true;
            if (lifecycleComponent._cloudwiseAction !== undefined) {
                let name = getNameFromComponent(lifecycleComponent);
                Logger.log(`Report Event - Component Did Mount - Name: ${name}`);
                lifecycleComponent._cloudwiseAction.reportEvent(`${name}.componentDidMount()`);
                lifecycleComponent._cloudwiseAction.leaveAction();
                lifecycleComponent._cloudwiseAction = undefined;
            }
        },
        _componentDidUpdateCloudwise: function (lifecycleComponent, prevProps, prevState, snapshot, componentDidUpdateOrig) {
            if (componentDidUpdateOrig !== undefined) {
                componentDidUpdateOrig(prevProps, prevState, snapshot);
            }
            if (lifecycleComponent._cloudwiseAction !== undefined) {
                let name = getNameFromComponent(lifecycleComponent);
                Logger.log(`Report Event - Component Did Update - Name: ${name}`);
                lifecycleComponent._cloudwiseAction.reportEvent(`${name}.componentDidUpdate()`);
                lifecycleComponent._cloudwiseAction.leaveAction();
                lifecycleComponent._cloudwiseAction = undefined;
            }
        },
        _renderCloudwise: function (lifecycleComponent, renderOrig) {
            if ((lifecycleComponent._cloudwiseMounted && Configuration_1.Configuration.isLifecycleUpdateEnabled())
                || (!lifecycleComponent._cloudwiseMounted)) {
                let actionPrefix = !lifecycleComponent._cloudwiseMounted ? "Render " : "Update ";
                let actionName = getNameFromComponent(lifecycleComponent);
                Logger.log(`Enter Action - ${actionPrefix}- Name: ${actionName}`);
                lifecycleComponent._cloudwiseAction = Cloudwise.enterAction(actionPrefix + actionName);
            }
            return renderOrig();
        },
        _componentWillUnmountCloudwise: function (lifecycleComponent, componentWillUnmountOrig) {
            if (componentWillUnmountOrig !== undefined) {
                componentWillUnmountOrig();
            }
            lifecycleComponent._cloudwiseMounted = false;
        }
    };
};
function getNameFromComponent(component) {
    if (isConstructorComponentConstructor(component.constructor)) {
        return component.constructor.displayName;
    }
    return component.constructor.name;
}
function isConstructorComponentConstructor(constructor) {
    return constructor.displayName !== undefined;
}
