"use strict";

const {
  nanoid
} = require('nanoid');
const pluralize = require('pluralize');
module.exports = {
  getRemovable,
  createId,
  deepQuery
};

// Returns document ids that have unsatisfied relations
// Example: a comment that references a post that doesn't exist
function getRemovable(db, opts) {
  const _ = this;
  const removable = [];
  _.each(db, (coll, collName) => {
    _.each(coll, doc => {
      _.each(doc, (value, key) => {
        if (new RegExp(`${opts.foreignKeySuffix}$`).test(key)) {
          // Remove foreign key suffix and pluralize it
          // Example postId -> posts
          const refName = pluralize.plural(key.replace(new RegExp(`${opts.foreignKeySuffix}$`), ''));
          // Test if table exists
          if (db[refName]) {
            // Test if references is defined in table
            const ref = _.getById(db[refName], value);
            if (_.isUndefined(ref)) {
              removable.push({
                name: collName,
                id: doc.id
              });
            }
          }
        }
      });
    });
  });
  return removable;
}

// Return incremented id or uuid
// Used to override lodash-id's createId with utils.createId
function createId(coll) {
  const _ = this;
  const idProperty = _.__id();
  if (_.isEmpty(coll)) {
    return 1;
  } else {
    let id = _(coll).maxBy(idProperty)[idProperty];

    // Increment integer id or generate string id
    return _.isFinite(id) ? ++id : nanoid(7);
  }
}
function deepQuery(value, q) {
  const _ = this;
  if (value && q) {
    if (_.isArray(value)) {
      for (let i = 0; i < value.length; i++) {
        if (_.deepQuery(value[i], q)) {
          return true;
        }
      }
    } else if (_.isObject(value) && !_.isArray(value)) {
      for (const k in value) {
        if (_.deepQuery(value[k], q)) {
          return true;
        }
      }
    } else if (value.toString().toLowerCase().indexOf(q) !== -1) {
      return true;
    }
  }
}