'use strict';

var UtilDocumentId = require('../../shared/utils/UtilDocumentId');
var _ = require('lodash/object');
var DataServiceUtil = require('../database/utils/DataServiceUtil');

//see details on https://mantis.formbird.com/view.php?id=12225
//info saved in accountSecurity document:
var ACCOUNT_SECURITY_DETAILS = ["provider", "apiKey", "apiHosts", "password", "pass"];
//info saved in accountControl document:
var ACCOUNT_CONTROL_DETAILS = ["attachKeys", "accessKeys", "verified", "accountPublicURL", "publicAccount"];

/**
 * Helper. If the target[key] is an array then concat it with accountInfo[key]. Else target[key] = accountInfo[key]
 * @param target
 * @param accountInfo
 * @param key
 */
function setAccountInfo(target, value, key){
    //concatenate if expected to be an array or else set the value in the account.
    if(Array.isArray(target[key]) && Array.isArray(value)){
        target[key] = target[key].concat(value);
    }else if(Array.isArray(target[key]) && !Array.isArray(value)){
        throw new Error("Expecting an array for account field but received something else: " + key );
    }else{
        target[key] = value;
    }
}

function buildAccountDocument(email, accountInfo, template){

    var documentId = accountInfo && accountInfo.documentId ? accountInfo.documentId : UtilDocumentId.generateId();

    var templateId = template ? template.documentId : config.get("accountTemplateId");

    var account = {
        documentId : documentId,
        email : email,
        defaultURL : config.get("defaultURL"),
        systemHeader : {
            templateId: templateId,
            createdWith: templateId,
            systemType: SharedConstants.SYSTEM_TYPE_ACCOUNT
        }
    };

    if(accountInfo){
        Object.keys(accountInfo).forEach(function (key) {
            if(ACCOUNT_SECURITY_DETAILS.indexOf(key) === -1 && ACCOUNT_CONTROL_DETAILS.indexOf(key) === -1){
                //all else save into the account document
                account[key] = accountInfo[key];
            }
        });
    }

    var user = {documentId: documentId};
    DataServiceUtil.applySystemType(account, template);
    DataServiceUtil.writeSystemHeader(account, SharedConstants.INSERT_OPERATION_TYPE, user, template);
    DataServiceUtil.imposeStandardDateTypeInSystemHeader(account);

    return account;

}

function buildAccountSecurityDocument(acc, encryptPwd, accountInfo, createdById, template){

    var templateId = template ? template.documentId : config.get("accountSecurityTemplateId");

    let accountRel = { documentId : acc.documentId };
    if (acc.systemHeader && acc.systemHeader.summaryName) {
        accountRel.name = acc.systemHeader.summaryName;
    }

    var securityDoc = {
        documentId : UtilDocumentId.generateId(),
        password : encryptPwd,
        provider : "local",
        apiKey : null,
        apiHosts : null,
        accountRel : [ accountRel ],
        systemHeader : {
            systemType : SharedConstants.SYSTEM_TYPE_ACCOUNT_SECURITY,
            templateId : templateId,
            createdWith: templateId,
            excludeGeneralSearch: true
        }
    };

    if(accountInfo){
        Object.keys(accountInfo).forEach(function (key) {
            if(ACCOUNT_SECURITY_DETAILS.indexOf(key) !== -1){

                var value = accountInfo[key];

                if(key === "pass"){
                    key = "password";
                }
                if (key === "password") {
                    value = encryptPwd;
                }

                setAccountInfo(securityDoc, value, key);
            }
        });
    }

    var user = {documentId: createdById ? createdById : acc.documentId};
    DataServiceUtil.writeSystemHeader(securityDoc, SharedConstants.INSERT_OPERATION_TYPE, user, template);
    DataServiceUtil.imposeStandardDateTypeInSystemHeader(securityDoc);

    return securityDoc;
}

function buildAccountControlDocument(acc, accountInfo, createdById, template){

    var templateId = template ? template.documentId : config.get("accountControlTemplateId");

    var controlDoc = {
        documentId : UtilDocumentId.generateId(),
        verified : false,
        attachKeys : [],
        accountRel : [
            {
                documentId : acc.documentId,
                name : acc.email
            }
        ],
        accountPublicURL : null,
        publicAccount : false,
        systemHeader : {
            systemType : SharedConstants.SYSTEM_TYPE_ACCOUNT_CONTROL,
            templateId : templateId,
            createdWith: templateId,
            excludeGeneralSearch: true
        }
    };

    if(accountInfo){
        Object.keys(accountInfo).forEach(function (key) {
            if(ACCOUNT_CONTROL_DETAILS.indexOf(key) !== -1){
                setAccountInfo(controlDoc, accountInfo[key], key);
            }
        });
    }

    var user = {documentId: createdById ? createdById : acc.documentId};
    DataServiceUtil.writeSystemHeader(controlDoc, SharedConstants.INSERT_OPERATION_TYPE, user, template);
    DataServiceUtil.imposeStandardDateTypeInSystemHeader(controlDoc);

    return controlDoc;
}

//helper. Copies attach keys into document's keyIds
function inheritKeys(template, document){
    //add keyIds based on template's attachKeys
    var attachKey = template.attachKeys;

    if (attachKey && attachKey.length > 0) {
        if (!document.systemHeader.keyIds) {
            document.systemHeader.keyIds = [];
        }

        document.systemHeader.keyIds = document.systemHeader.keyIds.concat(attachKey);
    }
}

module.exports.inheritKeys = inheritKeys;

module.exports.buildAccountDocument = buildAccountDocument;

module.exports.buildAccountSecurityDocument = buildAccountSecurityDocument;

module.exports.buildAccountControlDocument = buildAccountControlDocument;

module.exports.createPasswordResetDocument = function(email, hash, user) {
    var passwordRestDoc = {};
    passwordRestDoc.documentId = UtilDocumentId.generateId();
    passwordRestDoc.passwordResetAccountDocumentId = user.documentId;
    passwordRestDoc.resetTokenText = hash;
    passwordRestDoc.isActiveBool = true;
    var confAuth = config.get('authentication');

    var expiryDurationMin = _.get(confAuth, 'passwordReset.expiryDurationMinutes');
    if (!expiryDurationMin){
        expiryDurationMin = SharedConstants.DEFAULT_EXPIRY_DURATION_MINUTES;
    }
    var now = new Date();
    passwordRestDoc.passwordResetExpiryDate = new Date(now.setMinutes(now.getMinutes() + expiryDurationMin));

    passwordRestDoc.systemHeader = {};
    var templateId = _.get(confAuth, 'passwordReset.templateId');
    if (templateId){
        passwordRestDoc.systemHeader.templateId = templateId;
    }
    passwordRestDoc.systemHeader.createdDate = now;
    passwordRestDoc.systemHeader.createdBy  = user.documentId;
    passwordRestDoc.systemHeader.excludeGeneralSearch = false;
    passwordRestDoc.systemHeader.systemType = SharedConstants.SYSTEM_TYPE_PASSWORD_RESET;
    passwordRestDoc.systemHeader.versionId = UtilDocumentId.generateId();
    passwordRestDoc.systemHeader.currentVersion = true;


    return passwordRestDoc;
};

module.exports.createActivateAccountDocument = function(account, hash, user) {
  var passwordRestDoc = {};
  passwordRestDoc.documentId = UtilDocumentId.generateId();
  passwordRestDoc.passwordResetAccountDocumentId = account.documentId;
  passwordRestDoc.resetTokenText = hash;
  passwordRestDoc.isActiveBool = true;
  var confAuth = config.get('authentication');

  var expiryDurationMin = _.get(confAuth, 'passwordReset.expiryDurationMinutes');
  if (!expiryDurationMin){
    expiryDurationMin = SharedConstants.DEFAULT_EXPIRY_DURATION_MINUTES;
  }
  var now = new Date();
  passwordRestDoc.passwordResetExpiryDate = new Date(now.setMinutes(now.getMinutes() + expiryDurationMin));

  passwordRestDoc.systemHeader = {};
  var templateId = _.get(confAuth, 'passwordReset.templateId');
  if (templateId){
    passwordRestDoc.systemHeader.templateId = templateId;
  }
  passwordRestDoc.systemHeader.createdDate = now;
  passwordRestDoc.systemHeader.createdBy  = user.documentId;
  passwordRestDoc.systemHeader.excludeGeneralSearch = false;
  passwordRestDoc.systemHeader.systemType = SharedConstants.SYSTEM_TYPE_PASSWORD_RESET;
  passwordRestDoc.systemHeader.versionId = UtilDocumentId.generateId();
  passwordRestDoc.systemHeader.currentVersion = true;


  return passwordRestDoc;
};
//used in tests
module.exports._testUtils = {
    ACCOUNT_SECURITY_DETAILS : ACCOUNT_SECURITY_DETAILS,
    ACCOUNT_CONTROL_DETAILS : ACCOUNT_CONTROL_DETAILS
};
