"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;
    }
  }
}