



var config = require('../config');
var urljoin = require('url-join');
var request = require('request-promise-native');
var models = require('../models');
var api = require('./api');

var BOUNCE_ACTIONS = [{
  reason: "Needs more information",
  pattern: /^\\needs-info\b(.*)$/
}, {
  reason: "Incomplete",
  pattern: /^\\incomplete\b(.*)$/
}, {
  reason: "Contains bug",
  pattern: /^\\bug\b(.*)$/
}, {
  reason: "Needs redesign",
  pattern: /^\\redesign\b(.*)$/
}, {
  reason: 'Quality needs improvement',
  pattern: /^\\quality\b(.*)$/
}];
var REJECT_PATTERN = /^\\reject\b(.*)$/;

/**
 * Actions to perform on a submission.
 *
 * @typedef {Object} SubmissionActions
 * @prop {SubmissionAction[]} bounce - Bounce actions.
 * @prop {SubmissionAction[]} reject - Rejection actions.
 */

/**
 * A single action to perform on a submission.
 *
 * @typedef {Object} SubmissionAction
 * @prop {String} reason - The reason for the action.
 * @prop {String} message - The user-supplied message justifying the action.
 */

/**
 * Parse a text block and identify actions.
 *
 * @param {String} text - Text to parse.
 * @return {SubmissionActions} The parsed actions.
 */
function parseActions(text) {
  var actions = {
    bounce: [],
    reject: []
  };

  text.split('\n').forEach((line) => {
    BOUNCE_ACTIONS.forEach((bounceAction) => {
      var match = bounceAction.pattern.exec(line);
      if(match) {
        actions.bounce.push({
          reason: bounceAction.reason,
          message: match[1].trim()
        });
      }
    });

    var match = REJECT_PATTERN.exec(line);
    if(match) {
      actions.reject.push({
        message: match[1].trim()
      });
    }
  });

  return actions;
}



function handleNote(webhook) {
  var submission = webhook.merge_request || webhook.issue;
  var actions;

  var note = webhook.object_attributes;
  if(note.created_at != note.updated_at) {
    return null;
  }

  if(!submission) {
    return null;
  }

  actions = parseActions(note.note);

  if(!actions.bounce.length && !actions.reject.length) {
    return;
  }

  api.getGitlabUser(submission.author_id).then(function(author) {
    var bounces = actions.bounce.map((bounce) => {
      return models.createSubissionBounce({
        note: note,
        author: author,
        reason: bounce.reason,
        message: bounce.message,
        project: webhook.project,
        submission: submission,
        submissionType: note.noteable_type
      });
    });

    var rejects = actions.reject.map((reject) => {
      //TODO
      return reject;
    });

    //TODO send to elastic
    if(bounces.length) {
      console.log("bounces: %s", bounces);
    }

    if(rejects.length) {
      console.log("rejects: %s", rejects);
    }
  });
}

function handleMergeRequest(webhook) {
  if(webhook.object_attributes.action != 'open') {
    return;
  }

  var submission = models.createSubmission({
    webhook: webhook,
    submissionType: "MergeRequest"
  });
  //TODO send to elastic
  console.log("submission: %s", submission);
}

function handleIssue(webhook) {
  if(webhook.object_attributes.action != 'open') {
    return;
  }

  var submission = models.createSubmission({
    webhook: webhook,
    submissionType: "Issue"
  });
  console.log("submission: %s", submission);
}

function handleWebhook(body) {
  if(body.object_kind == 'note') {
    handleNote(body);
  } else if(body.object_kind == 'merge_request') {
    handleMergeRequest(body);
  } else if(body.object_kind == 'issue') {
    handleIssue(body);
  }
}


exports.handleWebhook = handleWebhook;

@@ -535,16 +535,73 @@
 b(.*)$/%0A
+%7D, %7B%0A  reason: 'Rejected',%0A  pattern: /%5E%5C%5Creject%5Cb(.*)$/%0A
 %7D%5D;%0Avar 
@@ -1947,36 +1947,65 @@
 t) %7B%0A    return 
-null
+Promise.reject(%22note is not new%22)
 ;%0A  %7D%0A%0A  if(!sub
@@ -2030,12 +2030,75 @@
 urn 
-null
+Promise.reject(%22note does not belong to an issue or merge request%22)
 ;%0A  
@@ -2197,32 +2197,83 @@
 th) %7B%0A    return
+ Promise.reject(%22not does not contain any actions%22)
 ;%0A  %7D%0A%0A  api.get
@@ -2265,16 +2265,23 @@
 %0A  %7D%0A%0A  
+return 
 api.getG
@@ -2932,24 +2932,37 @@
 ects);%0A    %7D
+%0A%0A    return;
 %0A  %7D);%0A%7D%0A%0Afu
@@ -3051,32 +3051,75 @@
 n') %7B%0A    return
+ Promise.reject('merge request is not new')
 ;%0A  %7D%0A%0A  var sub
@@ -3278,32 +3278,61 @@
 s%22, submission);
+%0A%0A  return Promise.resolve();
 %0A%7D%0A%0Afunction han
@@ -3408,24 +3408,59 @@
 %7B%0A    return
+ Promise.reject('issue is not new')
 ;%0A  %7D%0A%0A  var
@@ -3559,50 +3559,34 @@
 %7D);%0A
+%0A
   
-console.log(%22submission: %25s%22, submission
+return Promise.resolve(
 );%0A%7D
@@ -3653,24 +3653,31 @@
 ote') %7B%0A    
+return 
 handleNote(b
@@ -3733,24 +3733,31 @@
 est') %7B%0A    
+return 
 handleMergeR
@@ -3817,16 +3817,23 @@
 ) %7B%0A    
+return 
 handleIs
@@ -3846,16 +3846,89 @@
 dy);%0A  %7D
+%0A%0A  return Promise.reject(%60unexpected webhook type $%7Bbody.object_kind%7D%60);
 %0A%7D%0A%0A%0Aexp

add issue handler