import _ from 'lodash';
import debuglog from 'debug';

const debug = debuglog('SS:UserFacts');

const save = function save(key, value, cb) {
  const memory = this.user.memory;
  const userId = this.user.id;

  if (arguments.length !== 3) {
    console.log('WARNING\nValue not found in save function.');
    if (_.isFunction(value)) {
      cb = value;
      value = '';
    }
  }

  memory.db.get({ subject: key, predicate: userId }, (err, results) => {
    if (!_.isEmpty(results)) {
      memory.db.del(results[0], () => {
        memory.db.put({ subject: key, predicate: userId, object: value }, () => {
          cb(null, '');
        });
      });
    } else {
      memory.db.put({ subject: key, predicate: userId, object: value }, (err) => {
        cb(null, '');
      });
    }
  });
};

const hasItem = function hasItem(key, bool, cb) {
  const memory = this.user.memory;
  const userId = this.user.id;

  debug('getVar', key, bool, userId);
  memory.db.get({ subject: key, predicate: userId }, (err, res) => {
    if (!_.isEmpty(res)) {
      cb(null, (bool === 'true'));
    } else {
      cb(null, (bool === 'false'));
    }
  });
};

const get = function get(key, cb) {
  const memory = this.user.memory;
  const userId = this.user.id;

  debug('getVar', key, userId);

  memory.db.get({ subject: key, predicate: userId }, (err, res) => {
    if (res && res.length !== 0) {
      cb(err, res[0].object);
    } else {
      cb(err, '');
    }
  });
};

const createUserFact = function createUserFact(subject, predicate, object, cb) {
  const memory = this.user.memory;

  memory.db.get({ subject, predicate, object }, (err, results) => {
    if (!_.isEmpty(results)) {
      memory.db.del(results[0], () => {
        memory.db.put({ subject, predicate, object }, () => {
          cb(null, '');
        });
      });
    } else {
      memory.db.put({ subject, predicate, object }, (err) => {
        cb(null, '');
      });
    }
  });
};

const known = function known(bool, cb) {
  const memory = this.user.memory;
  const name = (this.message.names && !_.isEmpty(this.message.names)) ? this.message.names[0] : '';
  memory.db.get({ subject: name.toLowerCase() }, (err, res1) => {
    memory.db.get({ object: name.toLowerCase() }, (err, res2) => {
      if (_.isEmpty(res1) && _.isEmpty(res2)) {
        cb(null, (bool === 'false'));
      } else {
        cb(null, (bool === 'true'));
      }
    });
  });
};

const inTopic = function inTopic(topic, cb) {
  if (topic === this.user.currentTopic) {
    cb(null, 'true');
  } else {
    cb(null, 'false');
  }
};

export default {
  createUserFact,
  get,
  hasItem,
  inTopic,
  known,
  save,
};

@@ -1463,122 +1463,828 @@
 %7D;%0A%0A
-const createUserFact = function createUserFact(subject, predicate, object, cb) %7B%0A  const memory = this.user.memory
+// Query SV return O and if that failes query OV return S%0Aconst queryUserFact = function queryUserFact(subject, verb, cb) %7B%0A  var subject = subject.replace(/%5Cs/g,%22_%22).toLowerCase();%0A  var memory = this.user.memory;%0A  memory.db.get(%7Bsubject:subject, predicate:verb%7D, function(err, result)%7B%0A    if (!_.isEmpty(result)) %7B%0A      cb(null, result%5B0%5D.object);%0A    %7D else %7B%0A      memory.db.get(%7Bobject:subject, predicate:verb%7D, function(err, result)%7B%0A        if (!_.isEmpty(result)) %7B%0A          cb(null, result%5B0%5D.subject);%0A        %7D else %7B%0A          cb(null,%22%22);%0A        %7D%0A      %7D);%0A    %7D%0A  %7D);%0A%7D%0A%0Aconst createUserFact = function createUserFact(subject, predicate, object, cb) %7B%0A  const memory = this.user.memory;%0A%0A  var subject = subject.replace(/%5Cs/g,%22_%22).toLowerCase();%0A  var object = object.replace(/%5Cs/g,%22_%22).toLowerCase()
 ;%0A%0A 
@@ -3313,16 +3313,33 @@
 erFact,%0A
+  queryUserFact,%0A
   get,%0A 

Normalize the SO in create fact and add query fact to plugin