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

//@include lib_Class.js
//@include lib_sol.common.JsonUtils.js
//@include lib_sol.common.ix.ServiceBase.js

/**
 * @author ESt, ELO Digital Office GmbH
 * @version 1.0
 *
 * Retrieves all specified keywording forms' fields of a system.
 * If no keywording forms are specified in the `masks` parameter, all forms will be retrieved.
 *
 * # Example call
 *
 *      { "masks": ["Session"] }
 *
 * # Example result
 *
 *      {
 *        "Session": {                // technical mask name
 *          "id": "39",
 *          "name": "Kurstermin",     //translated mask name
 *          "fields": {
 *            "COURSE_REFERENCE": {   //technical field name
 *              "name": "Kursnummer", //translated field name
 *              "canEdit": true,
 *              "excludeFromISearch": false,
 *              "hidden": false,
 *              "max": 255,
 *              "min": 0,
 *              "readOnly": true,
 *              "required": false,
 *              "type": 3000
 *            },
 *            "COURSE_NAME": {
 *              "canEdit": true,
 *              "excludeFromISearch": false,
 *              "hidden": false,
 *              "max": 255,
 *              "min": 0,
 *              "name": "Name",
 *              "readOnly": true,
 *              "required": false,
 *              "type": 3000
 *            }
 *          }
 *        },
 *        ...
 *      }
 *
 * @cfg {String[]} masks An array of mask names or mask ids
 *
 * @eloix
 *
 * @requires sol.common.JsonUtils
 * @requires sol.common.ix.ServiceBase
 */
sol.define("sol.common.ix.services.GetKeywordingForms", {
  extend: "sol.common.ix.ServiceBase",

  docMaskProps: {
    canEdit: "canEdit",
    excludeFromISearch: "excludeFromISearch",
    hidden: "hidden",
    max: "max",
    min: "min",
    name: "name",
    readOnly: "readOnly",
    required: "required",
    type: "type"
  },

  getAllMasks: function () {
    return Array.prototype.slice.call(
        ixConnect.ix().createSord(
          null,
          "",
          new EditInfoZ(EditInfoC.mbMaskNames, new SordZ())
        ).maskNames
      )
      .map(function (mask) {
        return mask.id;
      });
  },

  getMask: function (maskId) {
    function checkoutMask (selector) {
      return ixConnect.ix().checkoutDocMask(String(maskId), selector, LockC.NO)
    }
    // two calls to checkoutMask are necessary, because mbAll returns the translated mask name
    var mask = checkoutMask(DocMaskC.mbAll);
    return {
      name: checkoutMask(new DocMaskZ(DocMaskC.mbGuid)).name, // technical mask name
      id: String(mask.id),
      translated: mask.name,
      lines: mask.lines
    };
  },

  addFieldInfo: function (ixField, fieldInfo, property) {
    var me = this;
    fieldInfo[me.docMaskProps[property]] = ixField[property];
    return fieldInfo;
  },

  getMaskFields: function (maskLines) {
    var me = this;

    return maskLines.reduce(function (fields, docMaskLine) {
      fields[String(docMaskLine.key)] = Object.keys(me.docMaskProps)
        .reduce(me.addFieldInfo.bind(me, docMaskLine), {});
      return fields;
    }, {});
  },

  addMaskFields: function (results, mask) {
    var me = this, maskInfo = me.getMask(mask);
    results[maskInfo.name] = {
      id: maskInfo.id,
      name: maskInfo.translated,
      fields: me.getMaskFields(maskInfo.lines)
    };
    return results;
  },

  /**
   * Returns all fields of specified masks or all masks.
   * @return {Object} one property for each mask
   */
  process: function () {
    var me = this, masks = me.masks || [];

    if (!Array.isArray(masks)) {
      throw "value of parameter `masks` must be an array";
    }

    return (masks.length ? masks : me.getAllMasks())
      .reduce(me.addMaskFields.bind(me), {});
  }
});

/**
 * @member sol.common.ix.services.GetKeywordingForms
 * @method RF_sol_common_service_GetKeywordingForms
 * @static
 * @inheritdoc sol.common.ix.ServiceBase#RF_ServiceBaseName
 */
function RF_sol_common_service_GetKeywordingForms(iXSEContext, args) {
  var logger = sol.create("sol.Logger", { scope: "sol.common.ix.services.GetKeywordingForms" }),
      stringify = sol.common.JsonUtils.stringifyQuick, params, result;
  logger.enter("RF_sol_common_service_GetKeywordingForms", args);

  params = sol.common.ix.RfUtils.parseAndCheckParams(iXSEContext, arguments.callee.name, args);
  result = stringify(sol.create("sol.common.ix.services.GetKeywordingForms", params).process());
  logger.exit("RF_sol_common_service_GetKeywordingForms");
  return result;
}