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

//@include lib_Class.js
//@include lib_sol.common.Cache.js
//@include lib_sol.common.ObjectUtils.js
//@include lib_sol.common.StringUtils.js
//@include lib_sol.common.JsonUtils.js
//@include lib_sol.common.Template.js
//@include lib_sol.common.AclUtils.js
//@include lib_sol.common.IxUtils.js
//@include lib_sol.common.SordUtils.js
//@include lib_sol.common.RepoUtils.js
//@include lib_sol.common.FileUtils.js
//@include lib_sol.common.ObjectFormatter.js
//@include lib_sol.common.ix.RfUtils.js
//@include lib_sol.common.ix.ServiceBase.js

var logger = sol.create("sol.Logger", { scope: "sol.common.ix.services.GetTemplates" });

/**
 * Retrieves the templates from all custom folders and has to be used as dynamic register.
 *
 * The folder description has to be the following text:
 *
 *     !? RF_sol_common_service_GetTemplates
 *
 * This uses the same algorithm as {@link sol.common.ix.services.GetConfig GetConfig} to determine the folders from where the templates will be loaded.
 *
 * E.g. if this is used on the folder
 *
 *     "ARCPATH:/Administration/Business Solutions/contract/Configuration/Contract types"
 *
 * it will load the templates from
 *
 *     "ARCPATH:/Administration/Business Solutions Custom/contract/Configuration/Contract types"
 *
 *
 * @author PZ, ELO Digital Office GmbH
 * @version 1.03.000
 *
 * @eloix
 * @requires  sol.common.IxUtils
 * @requires  sol.common.ix.ServiceBase
 * @requires  sol.common.ix.services.GetTemplates.Provider
 */
sol.define("sol.common.ix.services.GetTemplates", {
  extend: "sol.common.ix.ServiceBase",

  initialize: function (config) {
    var me = this;

    me.$super("sol.common.ix.ServiceBase", "initialize", [config]);
  },

  /**
   * Retrieves the objIds for templates from all custom folders.
   * @return {Object[]}
   */
  process: function () {
    var me = this,
        result = null,
        parentIdString, dbConnection;

    parentIdString = sol.common.ix.services.GetTemplates.Provider.getRelatedFolderIds(me.sord.id);

    if (parentIdString && (parentIdString.length > 0)) {
      dbConnection = new Packages.de.elo.ix.jscript.DBConnection();
      result = dbConnection.query("SELECT rel.objectid FROM relation rel JOIN objekte obj ON rel.objectid = obj.objid WHERE rel.parentid IN (" + parentIdString + ") AND rel.relstatus = 0 ORDER BY obj.objshort");
    }

    return result;
  }

});

/**
 * @protected
 * Internal cache for the folder IDs used to determine related templates.
 *
 * Uses the merge hierarchy like the configuration does.
 *
 * This should be uses only by {@link sol.common.ix.services.GetTemplates GetTemplates}.
 *
 * @requires sol.common.IxUtils
 */
sol.define("sol.common.ix.services.GetTemplates.Provider", {
  singleton: true,

  cache: [],

  /**
   * Read the folder IDs of all folders belonging to a specified one.
   * @param {String} originObjId
   * @return {String} A comma separated list of all related objIds
   */
  getRelatedFolderIds: function (originObjId) {
    var me = this,
        msg;

    if (!me.cache[originObjId]) {
      me.cache[originObjId] = me.idsToString(me.retrieveFolderIds(originObjId));
      msg = "Init cache for '{0}' -> {1}";
    } else {
      msg = "Cache hit for '{0}' -> {1}";
    }

    me.logger.debug([msg, originObjId, me.cache[originObjId]]);
    return me.cache[originObjId];
  },

  /**
   * @private
   * Retrieves the folder IDs.
   * @param {String} originObjId
   * @return {String[]} A comma list of all related objIds
   */
  retrieveFolderIds: function (originObjId) {
    var me = this,
        parentIds = [],
        mergehierarchy, defaultSord;

    mergehierarchy = me.getConfigHierarchy(originObjId);

    if (mergehierarchy) {

      if (mergehierarchy.defaultConfig) {
        defaultSord = ixConnectAdmin.ix().checkoutSord(mergehierarchy.defaultConfig.guid, SordC.mbOnlyId, LockC.NO);
        if (defaultSord) {
          parentIds.push(defaultSord.id);
        }
      }

      if (mergehierarchy.customConfigs && (mergehierarchy.customConfigs.length > 0)) {
        mergehierarchy.customConfigs.forEach(function (customCfg) {
          var customSord;
          if (customCfg && customCfg.guid) {
            customSord = ixConnectAdmin.ix().checkoutSord(customCfg.guid, SordC.mbOnlyId, LockC.NO);
            if (customSord) {
              parentIds.push(customSord.id);
            }
          }
        });
      }
    }
    return parentIds;
  },

  getConfigHierarchy: function (originObjId) {
    var anyParam, anyResult, jsonResult;

    anyParam = new Any();

    anyParam.type = ixConnect.CONST.ANY.TYPE_STRING;
    anyParam.stringValue = JSON.stringify({ compose: originObjId });

    anyResult = ixConnectAdmin.ix().executeRegisteredFunction("RF_sol_common_service_GetConfigHierarchy", anyParam);
    jsonResult = (anyResult && anyResult.stringValue) ? String(anyResult.stringValue) : "{}";

    return JSON.parse(jsonResult);
  },

  /**
   * @private
   * Converts an Array of objIds to an String for the SQL query.
   * @param {String[]} parentIds
   * @return {String}
   */
  idsToString: function (parentIds) {
    return parentIds.map(function (id) {
      return "'" + id + "'";
    }).join(",");
  }

});

/**
 * @member sol.common.ix.services.GetTemplates
 * @method RF_sol_common_service_GetTemplates
 * @static
 * @inheritdoc sol.common.ix.ServiceBase#RF_ServiceBaseName
 */
function RF_sol_common_service_GetTemplates(ec, args) {
  var params, service, result;
  logger.enter("RF_sol_common_service_GetTemplates", args);
  params = {};
  if (args.length > 0) {
    params.sord = args[0];
  }
  service = sol.create("sol.common.ix.services.GetTemplates", params);
  result = service.process();
  logger.exit("RF_sol_common_service_GetTemplates", result);
  return result;
}