/*
  Сервис интеграции ПП Парус 8 с WEB API
  Дополнительный модуль: Оперативный учёт (RCMN)
*/

//---------------------
// Глобальные константы
//---------------------

//Имена узлов/аргументов PWS-запроса
const SNODE_XREQUEST = "XREQUEST"; //Корневой узел запроса
const SNODE_XPAYLOAD = "XPAYLOAD"; //Полезная нагрузка запроса
const SNODE_XARGUMENTS = "XARGUMENTS"; //Коллекция аргументов
const SNODE_XARGUMENT = "XARGUMENT"; //Элемент аргумента
const SNODE_SNAME = "SNAME"; //Имя аргумента
const SNODE_VALUE = "VALUE"; //Значение аргумента
const SNODE_SSTORED = "SSTORED"; //Имя вызываемой хранимой процедуры
const SARG_SSEARCH = "SSEARCH"; //Аргумент строки поиска

//Пакет и хранимые процедуры расширения "Оперативный учёт"
const SPACKAGE_RCMN = "PKG_EXS_EXT_RCMN"; //Пакет расширения
const SSTORED_CLASSES_GET = "PKG_EXS_EXT_RCMN.CLASSES_GET"; //Получение списка классов
const SSTORED_OBJECTS_GET = "PKG_EXS_EXT_RCMN.OBJECTS_GET"; //Получение списка объектов
const SSTORED_DICT_RECS_GET = "PKG_EXS_EXT_RCMN.DICT_RECS_GET"; //Получение данных словаря
const RSTORED_SSEARCH_BASE64 = [SSTORED_CLASSES_GET, SSTORED_OBJECTS_GET, SSTORED_DICT_RECS_GET]; //Процедуры, для которых SSEARCH кодируется в Base64

//------------
// Тело модуля
//------------

//Кодирование строки в Base64 (UTF-8)
const encodeBase64Utf8 = sValue => Buffer.from(sValue, "utf8").toString("base64");

//Получение полезной нагрузки запроса
const getRequestPayload = request => {
    if (!request || typeof request !== "object") return null;
    const xRequest = request[SNODE_XREQUEST];
    if (!xRequest || typeof xRequest !== "object") return null;
    const xPayload = xRequest[SNODE_XPAYLOAD];
    if (!xPayload || typeof xPayload !== "object") return null;
    return xPayload;
};

//Получение имени хранимой процедуры из запроса
const getRequestStored = request => {
    const xPayload = getRequestPayload(request);
    if (!xPayload) return null;
    const sStored = xPayload[SNODE_SSTORED];
    return typeof sStored === "string" ? sStored : null;
};

//Проверка, что запрос относится к пакету расширения "Оперативный учёт"
const isRCMNRequest = request => {
    const sStored = getRequestStored(request);
    if (!sStored) return false;
    return sStored === SPACKAGE_RCMN || sStored.startsWith(SPACKAGE_RCMN + ".");
};

//Подготовка JSON-запроса расширения "Оперативный учёт" перед конвертацией в XML
const prepareRCMNRequestForXml = request => {
    //Получим полезную нагрузку запроса
    const xPayload = getRequestPayload(request);
    if (!xPayload) return request;
    //Проверим, что указана поддерживаемая хранимая процедура
    if (RSTORED_SSEARCH_BASE64.indexOf(xPayload[SNODE_SSTORED]) < 0) return request;
    //Получим коллекцию аргументов
    const xArguments = xPayload[SNODE_XARGUMENTS];
    if (!Array.isArray(xArguments)) return request;
    //Закодируем в Base64 значение аргумента SSEARCH (если есть)
    for (let i = 0; i < xArguments.length; i++) {
        const item = xArguments[i];
        const arg = item && (item[SNODE_XARGUMENT] || item);
        if (!arg || typeof arg !== "object" || arg[SNODE_SNAME] !== SARG_SSEARCH) continue;
        if (arg[SNODE_VALUE] === undefined || arg[SNODE_VALUE] === null) continue;
        arg[SNODE_VALUE] = encodeBase64Utf8(arg[SNODE_VALUE]);
    }
    return request;
};

//-----------------
// Интерфейс модуля
//-----------------

exports.isRCMNRequest = isRCMNRequest;
exports.prepareRCMNRequestForXml = prepareRCMNRequestForXml;
