'use strict';

var utils = require('./utils');

function _log(debug) {
  if (debug) {
    var args = Array.prototype.slice.call(arguments);
    args.shift();
    args.unshift("[greenlock/lib/middleware.js]");
    console.log.apply(console, args);
  }
}

module.exports.create = function (gl) {
  if (!gl.challenges['http-01'] || !gl.challenges['http-01'].get) {
    throw new Error("middleware requires challenge plugin with get method");
  }
  var log = gl.log || _log;

  log(gl.debug, "created middleware");
  return function (_app) {
    if (_app && 'function' !== typeof _app) {
      throw new Error("use greenlock.middleware() or greenlock.middleware(function (req, res) {})");
    }
    var prefix = gl.acmeChallengePrefix || '/.well-known/acme-challenge/';

    return function (req, res, next) {
      if (0 !== req.url.indexOf(prefix)) {
        log(gl.debug, "no match, skipping middleware");
        if ('function' === typeof _app) {
          _app(req, res, next);
        }
        else if ('function' === typeof next) {
          next();
        }
        else {
          res.statusCode = 500;
          res.end("[500] Developer Error: app.use('/', greenlock.middleware()) or greenlock.middleware(app)");
        }
        return;
      }

      log(gl.debug, "this must be tinder, 'cuz it's a match!");

      var token = req.url.slice(prefix.length);
      var hostname = req.hostname || (req.headers.host || '').toLowerCase().replace(/:.*/, '');

      log(gl.debug, "hostname", hostname, "token", token);

      var copy = utils.merge({ domains: [ hostname ] }, gl);
      copy = utils.tplCopy(copy);
      copy.challenge = {};
      copy.challenge.type = 'http-01'; // obviously...
      copy.challenge.identifier = { type: 'dns', value: hostname };
      copy.challenge.wildcard = false;
      copy.challenge.token = token;
      copy.challenge.altname = hostname;

      function cb(opts) {
        var secret = opts.keyAuthorization || opts;
        if (secret && 'string' === typeof secret) {
          res.setHeader('Content-Type', 'text/plain; charset=utf-8');
          res.end(secret);
          return;
        }
        eb(new Error("couldn't retrieve keyAuthorization"));
        return;
      }
      function eb(/*err*/) {
        res.statusCode = 404;
        res.setHeader('Content-Type', 'application/json; charset=utf-8');
        res.end('{ "error": { "message": "Error: These aren\'t the tokens you\'re looking for. Move along." } }');
        return;
      }
      function mb(err, result) {
        if (err) { eb(err); return; }
        cb(result);
      }

      var challenger = gl.challenges['http-01'].get;
      if (1 === challenger.length) {
        /*global Promise*/
        return Promise.resolve().then(function () {
          return gl.challenges['http-01'].get(copy);
        }).then(cb).catch(eb);
      } else if (2 === challenger.length) {
        gl.challenges['http-01'].get(copy, mb);
      } else {
        gl.challenges['http-01'].get(copy, hostname, token, mb);
      }

    };
  };
};