"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = require("../wrap/lodash");
const imitate_1 = require("../imitate");
const log_1 = require("../log");
const reset_1 = require("../reset");
const anything_1 = require("../stringify/anything");
function default_1(object, property, manualReplacement) {
    const isManual = arguments.length > 2;
    const realThingExists = object[property] ||
        Object.prototype.hasOwnProperty.call(object, property);
    if (isManual || realThingExists) {
        const realThing = object[property];
        return lodash_1.default.tap(getFake(isManual, property, manualReplacement, realThing), (fakeThing) => {
            object[property] = fakeThing;
            reset_1.default.onNextReset(() => {
                if (realThingExists) {
                    object[property] = realThing;
                }
                else {
                    delete object[property];
                }
            });
        });
    }
    else {
        log_1.default.error('td.replace', `No "${property}" property was found.`);
    }
}
exports.default = default_1;
var getFake = (isManual, property, manualReplacement, realThing) => {
    if (isManual) {
        warnIfTypeMismatch(property, manualReplacement, realThing);
        return manualReplacement;
    }
    else {
        return imitate_1.default(realThing, [property]);
    }
};
var warnIfTypeMismatch = (property, fakeThing, realThing) => {
    const fakeType = typeof fakeThing;
    const realType = typeof realThing;
    if (realThing !== undefined && fakeType !== realType) {
        log_1.default.warn('td.replace', `property "${property}" ${anything_1.default(realThing)} (${lodash_1.default.capitalize(realType)}) was replaced with ${anything_1.default(fakeThing)}, which has a different type (${lodash_1.default.capitalize(fakeType)}).`);
    }
};
