/**
 * Server side document access management logic is now at ServerAccessManager due to
 * issue https://mantis.formbird.com/view.php?id=12225.
 */

"use strict";

var SharedConstants = require('../constants/SharedConstants');
var lodashLang = require('lodash/lang');
var lodashString = require('lodash/string');

const filterNullKeyIds = keyId => {
    return lodashLang.isString(keyId) && lodashString.trim(keyId) && keyId !== "undefined";
};

const filterObjectOnlyAccessKeys = accessKey => {
    return lodashLang.isObject(accessKey);
};

function getUserAccessKeysForOperation(userAccountControlDocument, operation){

    const userAccessKeysForOperation = [];


    // See issue 12125 for more info about Account Control Documents

    var userAccessKeys = userAccountControlDocument.accessKeys;

    if (userAccessKeys) {
        userAccessKeys = userAccessKeys.filter(filterObjectOnlyAccessKeys);
        for (var x = 0; x < userAccessKeys.length; x++) {

            var userAccessKey = userAccessKeys[x];

            var key = userAccessKey.keyId ? userAccessKey.keyId : userAccessKey.documentId;

            if (key && userAccessKey.rights && userAccessKey.rights.indexOf(operation) > -1) {
                userAccessKeysForOperation.push(key);
            }

        }
    }

    return userAccessKeysForOperation;
}

// Retains the old behavior of 'hasPermission'; Returns true if user is allowed to perform at least 1 operation.
function hasPermission(targetDocument, userAccountControlDocument, operations, noTemplateAccessKeys){
    var noTemplateAccessKeyIds = noTemplateAccessKeys ? noTemplateAccessKeys : [];
    var documentKeyIds = targetDocument && targetDocument.systemHeader
    && targetDocument.systemHeader.keyIds ? targetDocument.systemHeader.keyIds : noTemplateAccessKeyIds;

    documentKeyIds = documentKeyIds.filter(filterNullKeyIds);

    for(var j = 0; j < operations.length ; j++){

        var operation = operations[j];

        // Documents without keys are unrestricted during non-offline operations.
        if ((!documentKeyIds || documentKeyIds.length === 0) && operation !== SharedConstants.OPERATION_TYPE_OFFLINE) {
            return true;
        }

        const userAccessKeysForOperation = getUserAccessKeysForOperation(userAccountControlDocument, operation);

        for (var i = 0; i < userAccessKeysForOperation.length; i++){
            if(documentKeyIds && documentKeyIds.indexOf(userAccessKeysForOperation[i]) > -1){
                return true;
            }
        }

    }

    return false;
}

var AccessManager = {

    checkAccess : function(targetDocument, userAccountControlDocument, operation, noTemplateAccessKeys){
        if (lodashLang.isArray(operation)) {
            return hasPermission(targetDocument, userAccountControlDocument, operation, noTemplateAccessKeys);
        }

        return hasPermission(targetDocument, userAccountControlDocument, [operation], noTemplateAccessKeys);
    },

    getUserAccessKeysForOperation : getUserAccessKeysForOperation,

    writeKeysToDocument: function writeKeysToDocument(document, template, userAccountControlDocument, defaultAttachKeys){

        // Prepare systemHeader and keyIds
        document.systemHeader = document.systemHeader ? document.systemHeader : {};
        document.systemHeader.keyIds = document.systemHeader.keyIds ? document.systemHeader.keyIds : [];

        var attachKeys = [].concat(document.systemHeader.keyIds);

        if (template && template.attachKeys && template.attachKeys.length){
            attachKeys = attachKeys.concat(template.attachKeys);
        }

        attachKeys = attachKeys.concat(userAccountControlDocument.attachKeys);
        if (defaultAttachKeys && defaultAttachKeys.length){
            attachKeys = attachKeys.concat(defaultAttachKeys);
        }
        document.systemHeader.keyIds = Array.from(new Set(attachKeys));

        document.systemHeader.keyIds = document.systemHeader.keyIds.filter(filterNullKeyIds);
    },

    hasPermission : function(targetDocument, userAccountControlDocument, operations) {
        var operationArr = operations.split(",");
        return hasPermission(targetDocument, userAccountControlDocument, operationArr);
    }

};

module.exports = AccessManager;
