const map = require('lodash/map');


const NotificationType = {
  UploadComplete: 'uploadComplete',
  CodeMoved: 'codeMoved'
}


class Notification
{
  constructor(values)
  {
    var self = this;

    self.id = values.id || values._id || null;
    self.uploadId = values.uploadId || null;
    self.codeId = values.codeId || null;
    self.userId = values.userId || null;
    self.type = values.type || NotificationType.UploadComplete;
    self.attempt = values.attempt || 0;
    self.metadata = values.metadata || null;
  }
}


class NotificationRepository
{
  constructor(store)
  {
    var self = this;
    self.store = store;
  }


  list()
  {
    var self = this;

    return new Promise((resolve, reject) =>
    {
      self.store.find({}, (err, docs) =>
      {
        if (err)
        {
          reject(err);
          return;
        }

        resolve(map(docs, (doc) => new Notification(doc)));
      });
    });
  }


  insert(notification)
  {
    var self = this;

    return new Promise((resolve, reject) =>
    {
      self.store.insert({
        userId: notification.userId,
        codeId: notification.codeId,
        uploadId: notification.uploadId,
        attempt: notification.attempt,
        type: notification.type,
        metadata: notification.metadata
      }, (err, dbNotification) =>
      {
        if (err)
        {
          reject(err);
          return;
        }

        resolve(dbNotification._id);
      });
    });
  }


  update(notification)
  {
    var self = this;

    return new Promise((resolve, reject) =>
    {
      self.store.update({ _id: notification.id }, { $set: {
        attempt: notification.attempt
      }},
        (err, numAffected) =>
        {
          if (err)
          {
            reject(err);
            return;
          }

          if (numAffected == 0)
          {
            reject();
          }

          resolve();
        });
    });
  }


  delete(notificationId)
  {
    var self = this;

    return new Promise((resolve, reject) =>
    {
      self.store.remove({ _id: notificationId }, (err, numRemoved) =>
      {
        if (err)
        {
          reject(err);
          return;
        }

        resolve();
      });
    });
  }
}


module.exports = {
  NotificationType,
  Notification,
  NotificationRepository
}