'use strict';

var q = require("q");
var SearchService = require('../../search/SearchService');
var UtilValidation = require('../../../shared/utils/UtilValidation');
var UtilCustomComponent = require('../../utils/UtilCustomComponent');
var logger = require('../../utils/Logger').loggers.get('db');
var NodeVM = require('vm2').NodeVM;

module.exports.preProcess = function(field, document, userId){
    var deferred = q.defer();

    var options = {
        targetOperation: SharedConstants.OPERATION_TYPE_EXECUTE,
        targetFieldNames: ["serverPreprocessorFunction", "preprocessorIsAsynchronous"]
    };

    UtilCustomComponent.getComponent(field, userId, options).then(function(result){

        const { getBuiltInWhitelist, getExternalWhitelist, getRoot } = require("./../../utils/UtilSandbox");

        try{
            var retVal;
            var customFunc = result.serverPreprocessorFunction;
            if (UtilValidation.hasValue(customFunc)) {
                var vm = new NodeVM({
                    sandbox: {
                        field : field,
                        document: document,
                        userId: userId,
                        logger: logger,
                        q: q},
                    require: {
                        external: getExternalWhitelist(),
                        builtin: getBuiltInWhitelist(),
                        root: getRoot()
                    }
                });

                var serverPreprocessorFunc = vm.run("module.exports = \n " + customFunc + ";", getRoot() + '/vm.js');
                if (result.preprocessorIsAsynchronous) {

                    serverPreprocessorFunc().then(function (retVal) {
                        deferred.resolve(retVal);
                    }, function(error) {
                        deferred.reject(error);
                    });
                } else {
                    retVal = serverPreprocessorFunc();
                    deferred.resolve(retVal);
                }
            } else {
                deferred.resolve(document);
            }
        }
        catch (err) {
            var errMsg = ("Error in running " + field.componentName + " preprocessor function : "  +
            err);
            logger.debug(errMsg);
            deferred.reject(errMsg);
        }


    },function (err) {
        deferred.reject(err);
    });

    return deferred.promise;
};

