// site-common.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0

'use strict';

const path = require('path');
const pug = require('pug');

const striptags = require('striptags');

const { SiteLog } = require(path.join(__dirname, 'site-log'));
const { SiteAsync } = require(path.join(__dirname, 'site-async'));

const Events = require('events');
class SiteCommon extends Events {

  constructor (dtp, component) {
    super();

    this.dtp = dtp;
    this.component = component;

    this.log = new SiteLog(dtp, component);
    this.appTemplateRoot = path.join(this.dtp.config.root, 'app', 'templates');

    this.jobQueues = { };
  }

  async start ( ) {/* I will need this, do not delete. */}

  async stop ( ) {
    let slugs = Object.keys(this.jobQueues);
    await SiteAsync.each(slugs, async (slug) => {
      const queue = this.jobQueues[slug];
      try {
        this.log.info('closing job queue');
        await queue.close();
        delete this.jobQueues[slug];
      } catch (error) {
        this.log.error('failed to close job queue', { name: slug, error });
      }
    }, 1);
  }

  async getJobQueue (name) {
    if (this.jobQueues[name]) {
      return this.jobQueues[name];
    }

    const { jobQueue: jobQueueService } = this.dtp.services;
    const config = this.dtp.config.jobQueues[name];

    this.log.info('connecting to job queue', { name, config });
    const queue = jobQueueService.getJobQueue(name, config);
    this.jobQueues[name] = queue;

    return queue;
  }

  regenerateSession (req) {
    return new Promise((resolve, reject) => {
      req.session.regenerate((err) => {
        if (err) {
          return reject(err);
        }
        resolve();
      });
    });
  }

  saveSession (req) {
    return new Promise((resolve, reject) => {
      req.session.save((err) => {
        if (err) {
          return reject(err);
        }
        resolve();
      });
    });
  }

  isSystemRoute (pathname) {
    return pathname.startsWith('/auth') ||
           pathname.startsWith('/image') ||
           pathname.startsWith('/manifest')
    ;
  }

  isValidString (text) {
    return text && (typeof text === 'string') && (text.length > 0);
  }

  loadAppTemplate (type, name) {
    return pug.compileFile(path.join(this.appTemplateRoot, type, name));
  }

  loadViewTemplate (filename) {
    const scriptFile = path.join(this.dtp.config.root, 'app', 'views', filename);
    return pug.compileFile(scriptFile);
  }

  compileViewTemplate (filename, options) {
    const scriptFile = path.join(this.dtp.config.root, 'app', 'views', filename);
    const pathObj = path.parse(scriptFile);
    options = Object.assign({
      filename: scriptFile,
      basedir: path.join(this.dtp.config.root, 'app', 'views'),
      doctype: 'html',
      name: pathObj.name,
    }, options);
    return pug.compileFileClient(scriptFile, options);
  }

  parseTagList (tagList, options) {
    options = Object.assign({
      lowercase: true,
      filter: [ ],
    }, options);
    return tagList
      .split(',')
      .map((metric) => {
        metric = striptags(metric.trim());
        return options.lowercase ? metric.toLowerCase() : metric;
      })
      .filter((metric) => {
        return  (typeof metric === 'string') &&
                (metric.length > 0) &&
                !options.filter.includes(metric.toLowerCase())
        ;
      });
  }
}

module.exports.SiteCommon = SiteCommon;