text: const async = require('async');
  const moment = require('moment');
  const stackify = require('stackify-logger');
  
  const loggingTools = require('auth0-log-extension-tools');
  const config = require('../lib/config');
  const logger = require('../lib/logger');
  
  module.exports = (storage) =>
    (req, res, next) => {
      const wtBody = (req.webtaskContext && req.webtaskContext.body) || req.body || {};
      const wtHead = (req.webtaskContext && req.webtaskContext.headers) || {};
      const isCron = (wtBody.schedule && wtBody.state === 'active') || (wtHead.referer === `${config('AUTH0_MANAGE_URL')}/` && wtHead['if-none-match']);
  
      if (!isCron) {
        return next();
      }
  
      stackify.start({
        apiKey: config('STACKIFY_APIKEY'),
        env: config('STACKIFY_ENV')
      });
  
      const getLogType = (type) => {
        return loggingTools.logTypes[type];
      };
  
      const onLogsReceived = (logs, callback) => {
        if (!logs || !logs.length) {
          return callback();
        }
  
        logger.info(`Sending ${logs.length} logs to Stackify.`);
  
        async.eachLimit(logs, 10, (log, cb) => {
          const logType = getLogType(log.type);
          const auth0Tag = '#auth0';
  
          switch(logType.level)
          {
            case 1: //Debug
              stackify.debug(auth0Tag, log);
              break;
            case 2: //Info
              stackify.info(auth0Tag, log);
              break;
            case 3: //Error
              stackify.error(`${auth0Tag} ${logType.name}`, log);
              break;
            case 4: //Critical
              stackify.fatal(`${auth0Tag} ${logType.name}`, log);
              break;
            default:
              stackify.info(auth0Tag, log);
          }
  
          //call callback to execute agains next 10 items        
          cb();
        }, (err) => {
          if (err) {
            return callback(err);
          }
  
          console.log('Upload complete.');
          return callback();
        });
      };
  
      const slack = new loggingTools.reporters.SlackReporter({
        hook: config('SLACK_INCOMING_WEBHOOK_URL'),
        username: 'auth0-logs-to-stackify',
        title: 'Logs To Stackify'
      });
  
      const options = {
        domain: config('AUTH0_DOMAIN'),
        clientId: config('AUTH0_CLIENT_ID'),
        clientSecret: config('AUTH0_CLIENT_SECRET'),
        batchSize: config('BATCH_SIZE'),
        startFrom: config('START_FROM'),
        logTypes: config('LOG_TYPES'),
        logLevel: config('LOG_LEVEL')
      };
  
      if (!options.batchSize || options.batchSize > 100) {
        options.batchSize = 100;
      }
  
      if (options.logTypes && !Array.isArray(options.logTypes)) {
        options.logTypes = options.logTypes.replace(/\s/g, '').split(',');
      }
  
      const auth0logger = new loggingTools.LogsProcessor(storage, options);
  
      const sendDailyReport = (lastReportDate) => {
        const current = new Date();
  
        const end = current.getTime();
        const start = end - 86400000;
        auth0logger.getReport(start, end)
          .then(report => slack.send(report, report.checkpoint))
          .then(() => storage.read())
          .then((data) => {
            data.lastReportDate = lastReportDate;
            return storage.write(data);
          });
      };
  
      const checkReportTime = () => {
        storage.read()
          .then((data) => {
            const now = moment().format('DD-MM-YYYY');
            const reportTime = config('DAILY_REPORT_TIME') || 16;
  
            if (data.lastReportDate !== now && new Date().getHours() >= reportTime) {
              sendDailyReport(now);
            }
          })
      };
  
      return auth0logger
        .run(onLogsReceived)
        .then(result => {
          if (result && result.status && result.status.error) {
            slack.send(result.status, result.checkpoint);
          } else if (config('SLACK_SEND_SUCCESS') === true || config('SLACK_SEND_SUCCESS') === 'true') {
            slack.send(result.status, result.checkpoint);
          }
          checkReportTime();
          res.json(result);
        })
        .catch(err => {
          slack.send({ error: err, logsProcessed: 0 }, null);
          checkReportTime();
          next(err);
        });
    };
  