#!/usr/bin/env node

/* eslint-disable no-console, node/shebang */

'use strict';

/*
 * This script generates the template a changelog by comparing a current version
 * with master. Run this, copy what's logged into the `CHANGELOG.md` and update
 * the top section based on the changes listed in "Community Contributions"
 *
 * Usage:
 *
 * bin/changelog.js
 */

var RSVP = require('rsvp');
var GitHubApi = require('github');
var execSync = require('child_process').execSync;

var github = new GitHubApi({ version: '3.0.0' });
var compareCommits = RSVP.denodeify(github.repos.compareCommits);
var currentVersion = process.env.PRIOR_VERSION;
var head = process.env.HEAD || execSync('git rev-parse HEAD', { encoding: 'UTF-8' });

compareCommits({
  user: 'emberjs',
  repo: 'ember.js',
  base: currentVersion,
  head: head,
})
  .then(processPages)
  .then(console.log)
  .catch(function(err) {
    console.error(err);
  });

function getCommitMessage(commitInfo) {
  var message = commitInfo.commit.message;

  if (message.indexOf('cherry picked from commit') > -1) {
    var cherryPickRegex = /cherry picked from commit ([a-z0-9]+)/;
    var originalCommit = cherryPickRegex.exec(message)[1];

    try {
      // command from http://stackoverflow.com/questions/8475448/find-merge-commit-which-include-a-specific-commit
      message = execSync(
        'commit=$((git rev-list ' +
          originalCommit +
          '..origin/master --ancestry-path | cat -n; git rev-list ' +
          originalCommit +
          '..origin/master --first-parent | cat -n) | sort -k2 | uniq -f1 -d | sort -n | tail -1 | cut -f2) && git show --format="%s\n\n%b" $commit',
        { encoding: 'utf8' }
      );
    } catch (e) {
      // ignored
    }
  }

  return message;
}

function processPages(res) {
  var contributions = res.commits
    .filter(function(commitInfo) {
      var message = commitInfo.commit.message;

      return (
        message.indexOf('Merge pull request #') > -1 || message.indexOf('cherry picked from') > -1
      );
    })
    .map(function(commitInfo) {
      var message = getCommitMessage(commitInfo);
      var match = message.match(/#(\d+) from (.*)\//);
      var result = {
        sha: commitInfo.sha,
      };

      if (match) {
        var numAndAuthor = match.slice(1, 3);

        result.number = numAndAuthor[0];
        result.title = message.split('\n\n')[1];
      } else {
        result.title = message.split('\n\n')[0];
      }

      return result;
    })
    .sort(function(a, b) {
      return a.number > b.number;
    })
    .map(function(pr) {
      var title = pr.title;
      var link;
      if (pr.number) {
        link =
          '[#' + pr.number + ']' + '(https://github.com/emberjs/ember.js/pull/' + pr.number + ')';
      } else {
        link =
          '[' + pr.sha.slice(0, 8) + '](https://github.com/emberjs/ember.js/commit/' + pr.sha + ')';
      }

      return '- ' + link + ' ' + title;
    })
    .join('\n');

  if (github.hasNextPage(res)) {
    return github.getNextPage(res).then(function(nextPage) {
      contributions += processPages(nextPage);
    });
  } else {
    return RSVP.resolve(contributions);
  }
}

@@ -357,19 +357,21 @@
 js%0A */%0A%0A
-var
+const
  RSVP = 
@@ -387,19 +387,21 @@
 rsvp');%0A
-var
+const
  GitHubA
@@ -424,19 +424,21 @@
 thub');%0A
-var
+const
  execSyn
@@ -477,19 +477,21 @@
 cSync;%0A%0A
-var
+const
  github 
@@ -529,19 +529,21 @@
 .0' %7D);%0A
-var
+const
  compare
@@ -597,19 +597,22 @@
 mmits);%0A
-var
+%0Aconst
  current
@@ -648,19 +648,21 @@
 ERSION;%0A
-var
+const
  head = 
@@ -975,19 +975,19 @@
 fo) %7B%0A  
-var
+let
  message
@@ -1080,19 +1080,19 @@
 ) %7B%0A    
-var
+let
  cherryP
@@ -1147,19 +1147,19 @@
 )/;%0A    
-var
+let
  origina
@@ -1800,19 +1800,19 @@
 es) %7B%0A  
-var
+let
  contrib
@@ -1865,35 +1865,35 @@
 itInfo) %7B%0A      
-var
+let
  message = commi
@@ -2083,19 +2083,19 @@
 %7B%0A      
-var
+let
  message
@@ -2133,19 +2133,19 @@
 ;%0A      
-var
+let
  match =
@@ -2188,19 +2188,19 @@
 ;%0A      
-var
+let
  result 
@@ -2269,19 +2269,19 @@
         
-var
+let
  numAndA
@@ -2597,19 +2597,19 @@
 %7B%0A      
-var
+let
  title =
@@ -2629,11 +2629,11 @@
     
-var
+let
  lin

Use `let/const` instead of `var`