'use strict';

var stormpath = require('stormpath');

/**
 * Allow a developer to exchange their API keys for an OAuth token.
 *
 * The URL this controller is bound to can be controlled via express-stormpath
 * settings.
 *
 * @method
 *
 * @param {Object} req - The http request.
 * @param {Object} res - The http response.
 */
module.exports = function (req, res) {
  var application = req.app.get('stormpathApplication');
  var config = req.app.get('stormpathConfig');
  var grantType = req.body && req.body.grant_type;
  var logger = req.app.get('stormpathLogger');

  function writeErrorResponse(err) {
    logger.info('An OAuth token exchange failed due to an improperly formed request.');
    return res.status(err.status || err.statusCode || 400).json(err);
  }

  if (req.method !== 'POST') {
    return res.status(405).end();
  }

  if (!grantType) {
    return writeErrorResponse({
      error: 'invalid_request'
    });
  }

  if (grantType === 'password' || grantType === 'refresh_token') {

    var authenticator = new stormpath.OAuthAuthenticator(application);
    authenticator.authenticate(req, function (err, authResult) {

      if (err) {
        return writeErrorResponse(err);
      }

      res.json(authResult.accessTokenResponse);
    });

  } else if (grantType === 'client_credentials') {
    application.authenticateApiRequest({
      request: req,
      ttl: config.web.oauth2.client_credentials.accessToken.ttl,
      scopeFactory: function (account, requestedScopes) {
        return requestedScopes;
      }
    }, function (err, authResult) {
      if (err) {
        return writeErrorResponse(err);
      }

      res.json(authResult.tokenResponse);
    });
  } else {
    writeErrorResponse({
      error: 'unsupported_grant_type'
    });
  }
};

@@ -469,59 +469,8 @@
 ');%0A
-  var grantType = req.body && req.body.grant_type;%0A
   va
@@ -715,20 +715,36 @@
 %0A  %7D%0A%0A  
-if (
+var isPostRequest = 
 req.meth
@@ -746,17 +746,17 @@
 .method 
-!
+=
 == 'POST
@@ -760,102 +760,125 @@
 OST'
-) %7B%0A    return res.status(405).end();%0A  %7D%0A%0A  if (!grantType) %7B%0A    return writeErrorResponse(%7B
+;%0A%0A  if (!req.body %7C%7C !isPostRequest) %7B%0A    return writeErrorResponse(%7B%0A      statusCode: !isPostRequest ? 405 : 400,
 %0A   
@@ -924,53 +924,68 @@
 %0A%0A  
-if (
+switch (req.body.
 grant
-Type === 'password' %7C%7C grantType ===
+_type) %7B%0A    case 'password':%0A    case
  're
@@ -996,21 +996,20 @@
 h_token'
-) %7B%0A%0A
+:%0A  
     var 
@@ -1071,16 +1071,19 @@
 ation);%0A
+%0A  
     auth
@@ -1139,17 +1139,18 @@
 sult) %7B%0A
-%0A
+  
       if
@@ -1150,32 +1150,34 @@
      if (err) %7B%0A
+  
         return w
@@ -1198,35 +1198,39 @@
 nse(err);%0A      
+  
 %7D%0A%0A
+  
       res.json(a
@@ -1269,39 +1269,36 @@
     
+  
 %7D);%0A
-%0A  %7D else if (grantType ===
+      break;%0A%0A    case
  'cl
@@ -1314,24 +1314,24 @@
 entials'
-) %7B%0A
+:%0A 
     
+ 
 applicat
@@ -1365,16 +1365,18 @@
 %7B%0A      
+  
 request:
@@ -1381,16 +1381,18 @@
 t: req,%0A
+  
       tt
@@ -1454,16 +1454,18 @@
 ,%0A      
+  
 scopeFac
@@ -1512,24 +1512,26 @@
 ) %7B%0A        
+  
 return reque
@@ -1548,18 +1548,22 @@
 ;%0A      
+  
 %7D%0A
+  
     %7D, f
@@ -1586,24 +1586,26 @@
 thResult) %7B%0A
+  
       if (er
@@ -1609,32 +1609,34 @@
 (err) %7B%0A        
+  
 return writeErro
@@ -1653,24 +1653,26 @@
 err);%0A      
+  
 %7D%0A%0A      res
@@ -1664,24 +1664,26 @@
    %7D%0A%0A      
+  
 res.json(aut
@@ -1714,27 +1714,47 @@
     
+  
 %7D);%0A  
-%7D else %7B
+    break;%0A%0A    default:
 %0A    
+  
 writ
@@ -1766,24 +1766,26 @@
 rResponse(%7B%0A
+  
       error:
@@ -1810,23 +1810,38 @@
 t_type'%0A    
-%7D)
+  %7D);%0A      break
 ;%0A  %7D%0A%7D;%0A

refactor get-token controller to increase readability