/**
 *   ЗАГРУЗКА СТАТЬИ НА СЕРВЕР
 *   Copyright © 2021, А.М.Гольдин. ISC license
 */
"use strict";

// Пишет аннотацию, текст статьи и библиографию в файл article.txt
// в папке со статьей; пишет данные о загруженной статье в базу
// Возвращает success или none
// data - это объект с содержимым статьи
// user - это данные клиента [3, "ivanov", "Иванов", "Ян", "Карлович"]
module.exports = async (data, user) => {
   try {      
      // Промисификатор записи файла
      const wrFile = cont => {
         return new Promise((resolve, reject) => {
            fs.writeFile(__dirname + `/../draft/${id}/article.txt`, cont, e => {
               if (e) reject("none"); else resolve("yes");
            })
         })
      };

      let LENS = {
         "pUDK":50, "pHead":200, "pUnit":10, "pAuthor":50, "pSved":100,
         "pEml":80, "pCoAuthors":150, "pAnnot":1000, "pKeyWords":200,
         "pText":50000, "pBibl":20000
      };

      // Проверяем, что пришло; обрезаем; вырезаем открывающие уголки
      let id = data["pID"];
      if(!/^\w{3,10}$/.test(id)) return "none";
      delete data["pID"];
      for (let k of Object.keys(data)) {
         if (!LENS[k]) return;
         data[k] = data[k].trim().substr(0, LENS[k]).trim();
         if (k != "pText") data[k] = data[k]
            .replace(/<</g, '¤').replace(/</g, '').replace(/¤/g, "<<");
         if (k == "pText") data[k] = data[k].replace(/<\s*script/g, '');
      }

      // Проверяем его роль
      let roles = "000";
      let staff = await dbFind("staff", {login: user[1]});
      if (staff[0]) roles = staff[0].roles.toString(2).padStart(3, '0');
      if (user[1] == ADMIN) roles = "111";
      
      // Есть ли такая статья и не опубликована ли она уже?
      // Проверяем полномочия приславшего статью (автор, ред. или корр.)
      let res = await dbFind("articles", {_id: id});
      if (!res.length)        return "none";
      if (res[0].status == 7) return "none";
      if (!roles[0] && !roles[1] && res[0].us != user[1]) return "none";

      let newStatus = Math.max(1, res[0].status);

      // Не подменил ли он имя автора?
      let auTr = res[0].author ?
                 res[0].author.split(' ') : [user[2], user[3]];
      let au = data["pAuthor"].split(' ');
      if (`${au[0]} ${au[1]}` !== `${auTr[0]} ${auTr[1]}`) return "none";
      
      // Пишем файл с аннотацией, текстом и библиографией
      let content =
         `${data["pAnnot"]}\n¤\n${data["pText"]}\n¤\n${data["pBibl"]}\n`;
      let resWrite = await wrFile(content);

      // Дата поступления статьи в редакцию
      let now = (new Date()).toISOString().split('T')[0]
              . replace(/(\d+)-(\d+)-(\d+)/, "$3.$2.$1"); 
      let dt1 = res[0].dt1 || now;

      // Соавторы - это объект
      // {ivanov: ["Иванов Иван Иванович", "Учащийся 8А класса"], petrov:...}
      let soavt = {},
          coAuthArr = data["pCoAuthors"].replace(/[^a-zA-Z0-9 ]/g, '')
                    . replace(/\s{2,}/g, ' ').trim().split(' ');
      if (coAuthArr[0]) for (let us of coAuthArr) {
         // Нет ли уже данных этого соавтора?
         // Если есть - оставляем их, если нет - пишем пустой массив
         let res = await dbFind("articles", {$where: function () {
            return (this._id == id && this.coauth[us] !== undefined);
         }});
         if (res.length) soavt[us] = res[0].coauth[us];
         else soavt[us] = [];
      }

      // Делаем запись в базу (остальные поля)
      if (resWrite == "yes") {
         let newArtObj = {
                 dt1: dt1,       // дата получения статьи редакцией
                 dt2: now,       // дата последней манипуляции со статьей
                  us: res[0].us,
              status: newStatus,
                 udk: data["pUDK"],
                head: data["pHead"],
                unit: data["pUnit"],
              author: data["pAuthor"],
                sved: data["pSved"],
                 eml: data["pEml"],
              coauth: soavt,
            keywords: data["pKeyWords"],
         }
         db.articles.update({_id: id}, {$set: newArtObj}, {});

         // Если отправлял автор, посылаем письма главному редактору и автору
         if (user[1] == res[0].us) {
            let isEdit = res[0].status ? "Отредактирована" : "Получена";
            await sendEml(ADMEML, "Поступила статья",
               `${isEdit} статья:\n`
            + `ID: ${id}\nАвтор: ${data["pAuthor"]}, ${data["pSved"]}\n`
            + `Название: ${data["pHead"]}`
            );         
            await sendEml(data["pEml"], `${isEdit} статья`,
               `Уважаемый(ая) ${data["pAuthor"]}!\n\n`
            + `Редакция сайта lycArch.urfu.ru получила вашу статью `
            + `«${data["pHead"]}». О дальнейших действиях редакции вы будете `
            + `проинформированы по электронной почте.\n\nДанное письмо `
            + `вы будете получать каждый раз при внесении вами изменений `
            + `в статью (редактировании). Благодарим вас за сотрудничество.`
            );
         }
         return "success";
      } 
   }
   catch(e) {return "none";}
};
