"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getEventsEndingAfter = exports.listByEndKey = exports.listKey = exports.getAllEvents = exports.escapeEvent = exports.getEventsByDate = exports.getEvent = exports.eventExists = exports.saveEvent = exports.purgeEvent = exports.restoreEvent = exports.deleteEvent = void 0;

var _validator = _interopRequireDefault(require("validator"));

var _responses = require("./responses");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

const {
  sortedSetAdd,
  sortedSetRemove,
  getSortedSetRange,
  getSortedSetRangeByScore,
  setObject,
  getObject,
  getObjects,
  exists,
  delete: deleteKey
} = require.main.require('./src/database');

const {
  fireHook
} = require.main.require('./src/plugins');

const {
  getCidsByPids,
  getCidByPid
} = require.main.require('./src/posts');

const listKey = 'plugins:calendar:events';
exports.listKey = listKey;
const listByEndKey = `${listKey}:byEnd`;
exports.listByEndKey = listByEndKey;

const saveEvent = event => {
  const objectKey = `${listKey}:pid:${event.pid}`;
  const endDate = event.repeats ? event.repeats.endDate || 9999999999999 : event.endDate;
  return Promise.all([sortedSetAdd(listKey, event.startDate, objectKey), sortedSetAdd(listByEndKey, endDate, objectKey), setObject(objectKey, event)]);
};

exports.saveEvent = saveEvent;

const deleteEvent = data => {
  const objectKey = `${listKey}:pid:${data.post.pid}`;
  return Promise.all([sortedSetRemove(listKey, objectKey), sortedSetRemove(listByEndKey, objectKey)]);
};

exports.deleteEvent = deleteEvent;

const restoreEvent = async data => {
  const objectKey = `${listKey}:pid:${data.post.pid}`;
  const event = await getObject(objectKey);
  const endDate = event.repeats ? event.repeats.endDate || 9999999999999 : event.endDate;
  return Promise.all([sortedSetAdd(listKey, event.startDate, objectKey), sortedSetAdd(listByEndKey, endDate, objectKey)]);
};

exports.restoreEvent = restoreEvent;

const purgeEvent = data => {
  const objectKey = `${listKey}:pid:${data.post.pid}`;
  return Promise.all([deleteKey(objectKey), (0, _responses.removeAll)(data.post.pid)]);
};

exports.purgeEvent = purgeEvent;

const fixEvent = event => {
  let repeats;

  try {
    repeats = JSON.parse(event.repeats);
  } catch (e) {
    repeats = null;
  }

  let reminders;

  try {
    reminders = JSON.parse(event.reminders);
  } catch (e) {
    reminders = [];
  }

  return _objectSpread({}, event, {
    repeats,
    reminders,
    startDate: parseInt(event.startDate, 10),
    endDate: parseInt(event.endDate, 10),
    mandatory: event.mandatory === true || event.mandatory === 'true',
    allday: event.allday === true || event.allday === 'true'
  });
};

const getEventsByDate = async (startDate, endDate) => {
  // may be possible eventually
  // except I need to do the intersection, not the union, of the sets
  // and I want events whose start date could be before the month starts
  // and whose end date could be after the month ends
  // const keys = await getSortedSetRangeByScore([
  //   listKey,
  //   listByEndKey,
  // ], 0, -1, startDate, endDate);
  // for now we have to do this,
  // and hope it isn't too hard on memory
  const [byStart, byEnd] = await Promise.all([// events that start before end date
  getSortedSetRangeByScore(listKey, 0, -1, 0, endDate), // events that end after start date
  getSortedSetRangeByScore(listByEndKey, 0, -1, startDate, +Infinity)]); // filter to events that only start before the endDate and end after the startDate

  const keys = byStart.filter(x => byEnd.includes(x));
  const events = (await getObjects(keys)).filter(Boolean);
  const cids = await getCidsByPids(events.map(event => event.pid));
  return events.map(fixEvent).map((event, i) => _objectSpread({}, event, {
    cid: cids[i]
  }));
};

exports.getEventsByDate = getEventsByDate;

const getAllEvents = async () => {
  const keys = await getSortedSetRange(listKey, 0, -1);
  const events = (await getObjects(keys)).filter(Boolean);
  return events.map(fixEvent);
};

exports.getAllEvents = getAllEvents;

const getEvent = async pid => {
  const event = await getObject(`${listKey}:pid:${pid}`);
  const cid = await getCidByPid(event.pid);
  return _objectSpread({}, fixEvent(event), {
    cid
  });
};

exports.getEvent = getEvent;

const getEventsEndingAfter = async endDate => {
  const keys = await getSortedSetRangeByScore(listByEndKey, 0, -1, endDate, +Infinity);
  const events = (await getObjects(keys)).filter(Boolean);
  return events.map(fixEvent);
};

exports.getEventsEndingAfter = getEventsEndingAfter;

const eventExists = pid => exists(`${listKey}:pid:${pid}`);

exports.eventExists = eventExists;

const escapeEvent = async event => {
  const [location, description] = await Promise.all([fireHook('filter:parse.raw', event.location || ''), fireHook('filter:parse.raw', event.description || '')]);
  return _objectSpread({}, event, {
    name: _validator.default.escape(event.name),
    location,
    description
  });
};

exports.escapeEvent = escapeEvent;
//# sourceMappingURL=event.js.map