'use strict';

var ServerAccessManager = require('../database/utils/ServerAccessManager');
var { getRedisClient } = require('./RedisClient');
var SharedConstants = require('../../shared/constants/SharedConstants');
var UtilError = require('../../shared/utils/UtilError');
var UtilDocument = require('../../shared/utils/UtilDocument');


function getData(redisKey, userId, options) {
    return new Promise((resolve, reject) => {
      getRedisClient().get(redisKey, (err, data) => {
            if (err) {
                reject(err);
            } else {
                if (data) {

                    var operation;
                    if (options && options.targetOperation) {
                        operation = options.targetOperation;
                    } else {
                        operation = SharedConstants.OPERATION_TYPE_READ;
                    }

                    let isJSONObject = false;
                    try {
                        data = JSON.parse(data);
                        isJSONObject = true;
                    } catch (e) {
                        logger.debug("Target data is not an JSON object. Consider another type.");
                    }

                    ServerAccessManager.checkAccess(data, userId, operation)
                        .then(hasAccess => {

                            if (hasAccess) {

                                logger.info("Got data from redis " + redisKey);

                                resolve(options && isJSONObject ?
                                    UtilDocument.filterDocumentFields(data, options.targetFieldNames) : data);

                            } else {

                                reject(UtilError.createForbiddenError(data, SharedConstants.OPERATION_TYPE_READ));
                            }

                        });
                } else {
                    resolve();
                }
            }
        });
    });
}

function setData(redisKey, data) {
    logger.info("Set Data to redis " + redisKey);
  getRedisClient().set(redisKey, data);
}

function removeData(redisKey, callBack) {
  getRedisClient().del(redisKey, function(err, response) {
        if (err) {
            callBack(err);
        } else{
            callBack(null, response);
        }
    });
}

function flushdb(){

    return new Promise((resolve, reject) => {

      getRedisClient().flushdb( function (err, succeeded) {

            const redisConfig = require('./RedisConfig').getConfig();

            const dbNumber = redisConfig != null ? redisConfig.databaseNumber : null;

            if (dbNumber) {
                logger.info(`RedisDB No.${dbNumber} flushed: ${succeeded}`);
            }else{
                logger.info(`RedisDB flushed: ${succeeded}`);
            }

            if(err){
                reject(err);
            }else{
                resolve(dbNumber);
            }
        });

    });

}

module.exports = {

    getData,

    setData,

    removeData,

    flushdb
};
