Websites.allow({
  insert: function (userId, doc) {
    // Ensure sane arguments.
    check(doc, {
      url: String,
      title: String,
      description: String,
      poster: Object,
      postDate: Date
    });

    // Reject anonymous inserts.
    if (!userId) {
      throw new Meteor.Error("logged-out", "User must be logged in to post a site.");
      // return false;
    }

    // Reject non-new inserts.
    const url = doc.url;

    if (Websites.findOne({ url })) {
      throw new Meteor.Error("duplicate", "User may only post new sites.");
      // return false;
    }

    // Reject wrong-looking URLs
    // TODO: find a validation package usable server-side.
    // The popular themeteorchef:jquery-validation appears to be client-only.
    // For now using a very limited check.
    const URL_BOGO_REGEX = /^https?:\/\/.+$/;
    if (!URL_BOGO_REGEX.test(doc.url)) {
      throw new Meteor.Error("bad-url", "Users may only post http(s) URLs.");
      // return false;
    }

    // Reject empty titles and descriptions.
    if (doc.title === "") {
      throw new Meteor.Error("empty-title", "Title may not be empty");
      // return false;
    }

    if (doc.description === "") {
      throw new Meteor.Error("empty-description", "Description may not be empty");
      // return false;
    }

    return true;
  },

  /**
   * Access check for update operations. NOT SAFE: needs deeper modifier checks.
   *
   * @param {String} userId
   *   The user attempting the modification.
   * @param {Object} doc
   *   The original document to modify.
   * @param {Array} fields
   *   The list of affected fields.
   * @param {Object} modifier
   *   The MongoDB update modifier.
   * @returns {boolean}
   *   True to allow update.
   */
  update: function (userId, doc, fields, modifier) {
    if (!userId) {
      throw new Meteor.Error("logged-out", "User must be logged to vote on a site.");
    }
    const orderedFields = fields.sort();
    if (!_.isEqual(orderedFields, ["minus", "minusScore"]) &&
      !_.isEqual(orderedFields, ["plus", "plusScore"]) &&
      !_.isEqual(orderedFields, ["minus", "minusScore", "plus", "plusScore"])) {
      throw new Meteor.Error("invalid-field", "May only update minus[Score] and plus[Score].");
    }

    // FIXME : check modifier.
    return true;
  }
});