// setting DANGER_ADMIN=1 in the env enables developer and admin without logins

import Validator from 'Validator';

export const developer_admin = process.env.DANGER_ADMIN === "1";


export class API {
  constructor(req, res) {
    this.req = req;
    this.res = res;
  }

  reply(status, data) {
    return this.res.status(status).json(data);
  }

  redirect(url, status=301) {
    return this.res.redirect(status, url);
  }

  error(status, err) {
    if(typeof err === 'string') {
      return this.res.status(status).send({message: err});
    } else {
      return this.res.status(status).send(err);
    }
  }

  get user_authenticated() {
    return this.req.user !== undefined;
  }

  get admin_authenticated() {
    return this.req.user !== undefined && this.req.user.admin === 1;
  }

  get user() {
    return this.req.user;
  }

  validate(rules, extra) {
    const form = this.req.method === "GET" ? this.req.query : this.req.body;
    let validation = Validator.make(form, rules);

    // keep the rules as they're needed everywhere
    form._rules = rules;

    // BUG: validator has a bug that considers an empty
    // form valid even if there are required rules
    if(Object.getOwnPropertyNames(form).length === 0) {
      // add in a fake entry in the form
      form["_empty"] = null;
      // validate it
      form._valid = validation.passes();
      // then remove _empty to keep it clean
      delete form["_empty"];
    } else {
      form._valid = validation.passes();
    }

    form._errors = validation.getErrors();
    if(extra) extra(form);
    return form;
  }

  validation_error(res, form) {
    return res.status(400).json(form);
  }

  clean_form(form, rules, extras=[]) {
    // what I wouldn't give for set operations
    for(let [key, rule] of Object.entries(form)) {
      if(!(key in rules)) {
        delete form[key];
      }
    }

    for(let field of extras) {
      delete form[field];
    }
  }
}

export const defer = () => {
  let res;
  let rej;

  let promise = new Promise((resolve, reject) => {
    res = resolve;
    rej = reject;
  });

  promise.resolve = res;
  promise.reject = rej;

  return promise;
}
