#!/usr/bin/env node

'use strict';

const git = require('git-child');
const del = require('del');
const chalk = require('chalk');
const exec = require('promised-exec');
const argv = require('yargs').argv;

const RELEASES_BRANCH = process.env.BR_RELEASES_BRANCH || argv.b || 'releases';
const GH_TOKEN = process.env.GH_TOKEN || argv.t;
const DIST_DIR = process.env.BR_DIST_DIR || argv.d || 'dist';
const COMMIT_MESSAGE = process.env.BR_DIST_DIR || argv.m || 'Release v%ver%';
const BUILD_SCRIPT = process.env.BR_BUILD_SCRIPT || argv.s || 'build-dist';

function main() {
  branchRelease()
  .catch(err => fail(err));
}

function branchRelease() {
  return wasVersionChanged().then(versions => {
    if (versions[0] !== versions[1]) return buildAndPublish(versions[1]);
    log(chalk.green('Package version was not changed'));
  });
}

function wasVersionChanged() {
  let version;
  return git.checkout('master')
  .then(() => git.show('HEAD:package.json'))
  .then(contents => {
    version = JSON.parse(contents).version;
    return git.show('HEAD^:package.json')
  })
  .then(contents => {
    const prevVersion = JSON.parse(contents).version;
    return [prevVersion, version];
  })
}

function buildAndPublish(version) {
  log(`running: 'git checkout -B ${RELEASES_BRANCH}'`);
  return git.checkout({B: RELEASES_BRANCH})
  .then(() => {
    log(`running: 'git pull origin ${RELEASES_BRANCH}'`);
    return git.pull(['origin', RELEASES_BRANCH]);
  })
  .then(() => {
    log(`running: 'git merge master'`);
    return git.merge('master');
  })
  .then(() => {
    log('Clearing dist folder');
    return del([ DIST_DIR + '/**/*' ]);
  })
  .then(() => {
    let buildCommand = `npm run-script ${BUILD_SCRIPT}`;
    log(`running: '${buildCommand}'`);
    return exec(buildCommand);
  })
  .then(() => {
    log(`running: 'git add .'`);
    return git.add('.');
  })
  .then(() => {
    log(`running: 'git add ${DIST_DIR} -f'`);
    return git.add({
      _: DIST_DIR,
      f: true
    });
  })
  .then(() => {
    const commitMessage = COMMIT_MESSAGE.replace('%ver%', version);
    log(`running: 'git commit -m ${commitMessage}'`);
    return git.commit({m: commitMessage});
  })
  .then(() => {
    log(`running: 'git tag ${version}'`);
    return git.tag(version);
  })
  .then(() => {
    return git.config({
      'get':true,
      '_': 'remote.origin.url'
    });
  })
  .then((remoteUrl) => {
    let repoRef = remoteUrl.split('@').length > 1 ? remoteUrl.split('@')[1] : remoteUrl;
    repoRef = repoRef.trim();
    if (repoRef.startsWith('https://'))
      repoRef = repoRef.substring(8);


    let args = `${RELEASES_BRANCH}:${RELEASES_BRANCH}`;
    if (GH_TOKEN) {
      args = [`https://${GH_TOKEN}@${repoRef}`, args];
    }
    log(`running: 'git push --follow-tags`);
    return git.push({
      'follow-tags': true,
      '_': args
    });
  })
  .finally(() => {
    log('switching back to master branch');
    return git.checkout('master');
  })
  .then(() => {
    log(chalk.green("Released successfully"))
  })
}

function log() {
  console.log.apply(console, arguments);
}

function fail(err) {
  let message = err.message || err.string;
  if (GH_TOKEN)
    message = message.replace(GH_TOKEN, 'xxGH_TOKENxx');
  log(chalk.red('Release failed:'))
  log(chalk.red(message));
  process.exit(1);
}

if (require.main === module) {
  main();
}

module.exports = branchRelease;

@@ -1218,16 +1218,32 @@
 sion) %7B%0A
+  let repoRef;%0A%0A
   log(%60r
@@ -2415,20 +2415,16 @@
 %3E %7B%0A    
-let 
 repoRef 
@@ -2774,22 +2774,209 @@
 push
- --follow
+'%60);%0A    return git.push(%7B%0A      '_': args%0A    %7D);%0A  %7D)%0A  .then(() =%3E %7B%0A    let args = %5B%5D;%0A    if (GH_TOKEN) %7B%0A      args = %5B%60https://$%7BGH_TOKEN%7D@$%7BrepoRef%7D%60%5D;%0A    %7D%0A    log(%60running: 'git push -
 -tags
+'
 %60);%0A
@@ -3008,15 +3008,8 @@
    '
-follow-
 tags

Add push --tags step