importPackage(Packages.de.elo.ix.client);

//@include lib_Class.js
//@include lib_sol.common.SordUtils.js
//@include lib_sol.common.AclUtils.js
//@include lib_sol.common.AsyncUtils.js
//@include lib_sol.common.WfUtils.js
//@include lib_sol.common.ix.RfUtils.js
//@include lib_sol.common.ix.FunctionBase.js
//@include lib_sol.contact.Utils.js

var logger = sol.create("sol.Logger", { scope: "sol.contact.ix.functions.MoveContact" });

/**
 * Moves a contact element to a new location in a company if possible.
 *
 * # As workflow node
 *
 * ObjId is set based on the element that the workflow is attached to.
 *
 * # As IX function call
 *
 * In addition to the workflow node configuration the objId must be passed.
 *
 *     sol.common.IxUtils.execute('RF_sol_contact_function_MoveContact', {
 *       objId: "4711"
 *     });
 *
 * |Property|Description|
 * |:------|:------|
 * |contactlist.referenceField|Reference field to the contact list|
 * |contactlist.maskName|Mask for contact lists|
 * |company.referenceField|Reference field to the company|
 * |company.maskName|Mask for companies|
 *
 * @author JHR, ELO Digital Office GmbH
 * @version 1.0
 *
 * @eloix
 * @requires  handlebars
 * @requires  sol.common.SordUtils
 * @requires  sol.common.WfUtils
 * @requires  sol.common.ix.RfUtils
 * @requires  sol.common.ix.FunctionBase
 *
 */
sol.define("sol.contact.ix.functions.MoveContact", {
  extend: "sol.common.ix.FunctionBase",

  requiredConfig: ["objId"],

  /**
   * @cfg {String} objId (required)
   * Object ID
   */

  /**
   * @cfg {Boolean} [update=false]
   * Update mode
   */

  initialize: function (config) {
    var me = this;
    me.$super("sol.common.ix.FunctionBase", "initialize", [config]);
    me.config = sol.contact.Utils.loadConfig();
  },

  /**
   * Moves the contact element to a new location in a company or contact list if possible.
   */
  process: function () {
    var me = this,
        alreadyMoved = false,
        sord, rightsConfig, configPart, currentUserRightsEntry;

    me.logger.debug(["Move contact element: objId={0}, ixConnect.user={1}, update={2}", me.objId + "", ixConnect.loginResult.user.name + "", me.update]);

    sord = ixConnect.ix().checkoutSord(me.objId, EditInfoC.mbSord, LockC.NO).sord;

    if (!sol.contact.Utils.isCompany(sord)) {
      alreadyMoved = me.moveByReferenceField(sord, "CompanyReference", me.config.company.maskName, me.config.company.referenceField);
    }

    if (!alreadyMoved) {
      me.moveByReferenceField(sord, "ContactlistReference", me.config.contactlist.maskName, me.config.contactlist.referenceField);
    }

    if (!me.update) {
      configPart = sol.contact.Utils.getConfigPart(me.config, sord);
      currentUserRightsEntry = { name: "$CURRENTUSER", rights: { r: true, w: true, d: true, e: true, l: true, p: true } };

      rightsConfig = configPart.rightsConfig;

      if (rightsConfig) {
        rightsConfig.users = rightsConfig.users || [];
        rightsConfig.users.push(currentUserRightsEntry);
      } else {
        rightsConfig = {
          mode: "SET",
          inherit: true,
          users: [currentUserRightsEntry]
        };
      }

      me.logger.debug(["Set contact element rights: objId={0}, rightsConfig={1}", me.objId + "", JSON.stringify(rightsConfig)]);

      sol.common.AclUtils.changeRightsInBackground(me.objId, rightsConfig);
    }
  },

  /**
   * @private
   * Moves the contract to the correct lcation.
   * @param {de.elo.ix.client.Sord} sord
   * @param {String} refName
   * @param {String} targetMask
   * @param {String} refField
   * @return {Boolean}
   */
  moveByReferenceField: function (sord, refName, targetMask, refField) {
    var me = this,
        ref = sol.common.SordUtils.getObjKeyValue(sord, refField),
        targetSord, oldParentId;
    if (ref) {
      targetSord = me.findSord({ mask: targetMask, objKeyData: [{ key: refField, value: ref }] });
      if (targetSord) {
        oldParentId = ixConnect.ix().checkoutSord(sord.id, EditInfoC.mbOnlyId, LockC.NO).sord.parentId;
        me.logger.info(["move sord: ({0}) from -> ({1}) to ({2})", sord.id, oldParentId, targetSord.id]);
        ixConnectAdmin.ix().refSord(oldParentId, targetSord.id, sord.id, -1);
        return true;
      } else {
        me.logger.error(["could not resolve {0}: {1}", refName, ref]);
        throw "could not resolve " + refName + ": " + ref;
      }
    }
  },

  /**
   * @private
   * Retrieves a sord by index value
   * @param {Object} cfg
   * @return {de.elo.ix.client.Sord}
   */
  findSord: function (cfg) {
    try {
      return sol.common.RepoUtils.getSord(sol.common.RepoUtils.getObjIdByIndex(cfg));
    } catch (ignore) {
      // ignore
    }
  }
});


/**
 * @member sol.contact.ix.functions.MoveContact
 * @static
 * @inheritdoc sol.common.ix.FunctionBase#onEnterNode
 */
function onEnterNode(clInfo, userId, wFDiagram, nodeId) {
  logger.enter("onEnterNode_MoveContact", { flowId: wFDiagram.id, nodeId: nodeId });
  var params = sol.common.WfUtils.parseAndCheckParams(wFDiagram, nodeId),
      module;

  params.objId = wFDiagram.objId;
  module = sol.create("sol.contact.ix.functions.MoveContact", params);

  module.process();

  logger.exit("onEnterNode_MoveContact");
}


/**
 * @member sol.contact.ix.functions.MoveContact
 * @static
 * @inheritdoc sol.common.ix.FunctionBase#onExitNode
 */
function onExitNode(clInfo, userId, wFDiagram, nodeId) {
  logger.enter("onExitNode_MoveContact", { flowId: wFDiagram.id, nodeId: nodeId });
  var params = sol.common.WfUtils.parseAndCheckParams(wFDiagram, nodeId),
      module;

  params.objId = wFDiagram.objId;
  module = sol.create("sol.contact.ix.functions.MoveContact", params);

  module.process();

  logger.exit("onExitNode_MoveContact");
}


/**
 * @member sol.contact.ix.functions.MoveContact
 * @method RF_sol_contact_function_MoveContact
 * @static
 * @inheritdoc sol.common.ix.FunctionBase#RF_FunctionName
 */
function RF_sol_contact_function_MoveContact(iXSEContext, args) {
  logger.enter("RF_sol_contact_function_MoveContact", args);
  var params, module;

  params = sol.common.ix.RfUtils.parseAndCheckParams(iXSEContext, arguments.callee.name, args, "objId");
  module = sol.create("sol.contact.ix.functions.MoveContact", params);

  module.process();

  logger.exit("RF_sol_contact_function_MoveContact");
}