'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _util = require('util');

var _util2 = _interopRequireDefault(_util);

var _yeomanGenerator = require('yeoman-generator');

var _yeomanGenerator2 = _interopRequireDefault(_yeomanGenerator);

var _child_process = require('child_process');

var _chalk = require('chalk');

var _chalk2 = _interopRequireDefault(_chalk);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _underscore = require('underscore.string');

var _underscore2 = _interopRequireDefault(_underscore);

var _generatorBase = require('../generator-base');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var Generator = function (_Base) {
  _inherits(Generator, _Base);

  function Generator() {
    var _Object$getPrototypeO;

    _classCallCheck(this, Generator);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(Generator)).call.apply(_Object$getPrototypeO, [this].concat(args)));

    _this.sourceRoot(_path2.default.join(__dirname, '../../templates/heroku'));
    return _this;
  }

  _createClass(Generator, [{
    key: 'initializing',
    value: function initializing() {
      return (0, _generatorBase.genNamedBase)(this);
    }
  }, {
    key: 'askForName',
    value: function askForName() {
      var _this2 = this;

      var done = this.async();

      var prompts = [{
        name: 'deployedName',
        message: 'Name to deploy as (Leave blank for a random name):'
      }];

      return this.prompt(prompts).then(function (props) {
        _this2.deployedName = _underscore2.default.slugify(props.deployedName);
      });
    }
  }, {
    key: 'askForRegion',
    value: function askForRegion() {
      var _this3 = this;

      var done = this.async();

      var prompts = [{
        type: 'list',
        name: 'region',
        message: 'On which region do you want to deploy ?',
        choices: ['US', 'EU'],
        default: 0
      }];

      return this.prompt(prompts).then(function (props) {
        _this3.region = props.region.toLowerCase();
      });
    }
  }, {
    key: 'checkInstallation',
    value: function checkInstallation() {
      var _this4 = this;

      if (this.abort) return;
      var done = this.async();

      (0, _child_process.exec)('heroku --version', function (err) {
        if (err) {
          _this4.log.error('You don\'t have the Heroku Toolbelt installed. Grab it from https://toolbelt.heroku.com/');
          _this4.abort = true;
        }
        done();
      });
    }
  }, {
    key: 'gitInit',
    value: function gitInit() {
      var _this5 = this;

      if (this.abort) return;
      var done = this.async();

      this.log(_chalk2.default.bold('\nInitializing deployment repo'));
      this.mkdir('dist');
      var child = (0, _child_process.exec)('git init', { cwd: 'dist' }, function (err, stdout, stderr) {
        done();
      });

      child.stdout.on('data', function (data) {
        _this5.log(data.toString());
      });
    }
  }, {
    key: 'herokuCreate',
    value: function herokuCreate() {
      var _this6 = this;

      if (this.abort) return;
      var done = this.async();
      var regionParams = this.region !== 'us' ? ' --region ' + this.region : '';

      this.log(_chalk2.default.bold('Creating heroku app and setting node environment'));
      var child = (0, _child_process.exec)('heroku apps:create ' + (this.deployedName + regionParams) + ' && heroku config:set NODE_ENV=production', { cwd: 'dist' }, function (err, stdout, stderr) {
        if (err) {
          _this6.abort = true;
          _this6.log.error(err);
        } else {
          _this6.log('stdout: ' + stdout);
        }
        done();
      });

      child.stdout.on('data', function (data) {
        _this6.log(data.toString());
      });
    }
  }, {
    key: 'copyProcfile',
    value: function copyProcfile() {
      if (this.abort) return;
      var done = this.async();
      this.log(_chalk2.default.bold('Creating Procfile'));
      this.copy('Procfile', 'dist/Procfile');
      this.conflicter.resolve(function (err) {
        done();
      });
    }
  }, {
    key: 'build',
    value: function build() {
      var _this7 = this;

      if (this.abort) return;
      var done = this.async();

      this.log(_chalk2.default.bold('\nBuilding dist folder, please wait...'));

      var child = (0, _child_process.exec)('gulp build', function (err, stdout) {
        done();
      });

      child.stdout.on('data', function (data) {
        _this7.log(data.toString());
      });
    }
  }, {
    key: 'gitInit',
    value: function gitInit() {
      var _this8 = this;

      if (this.abort) return;
      var done = this.async();

      this.log(_chalk2.default.bold('Adding files for initial commit'));
      var child = (0, _child_process.exec)('git add -A && git commit -m "Initial commit"', { cwd: 'dist' }, function (err, stdout, stderr) {
        if (stdout.search('nothing to commit') >= 0) {
          this.log('Re-pushing the existing "dist" build...');
        } else if (err) {
          this.log.error(err);
        } else {
          this.log(_chalk2.default.green('Done, without errors.'));
        }
        done();
      }.bind(this));

      child.stdout.on('data', function (data) {
        _this8.log(data.toString());
      });
    }
  }, {
    key: 'gitForcePush',
    value: function gitForcePush() {
      var _this9 = this;

      if (this.abort) return;
      var done = this.async();

      this.log(_chalk2.default.bold("\nUploading your initial application code.\n This may take " + _chalk2.default.cyan('several minutes') + " depending on your connection speed..."));

      var child = (0, _child_process.exec)('git push -f heroku master', { cwd: 'dist' }, function (err, stdout, stderr) {
        if (err) {
          _this9.log.error(err);
        } else {
          var hasWarning = false;

          if (_this9.filters.mongoose) {
            _this9.log(_chalk2.default.yellow('\nBecause you\'re using mongoose, you must add mongoDB to your heroku app.\n\tfrom `/dist`: ' + _chalk2.default.bold('heroku addons:create mongolab') + '\n'));
            hasWarning = true;
          }

          var oauthMessage = function oauthMessage(strategy) {
            return _chalk2.default.yellow('\nYou will need to set environment variables for ' + strategy + ' auth. From `/dist`:\n\t' + _chalk2.default.bold('heroku config:set ' + strategy.toUpperCase() + '_ID=appId') + '\n\t' + _chalk2.default.bold('heroku config:set ' + strategy.toUpperCase() + '_SECRET=secret') + '\n');
          };
          if (_this9.filters.facebookAuth) {
            _this9.log(oauthMessage('facebook'));
            hasWarning = true;
          }
          if (_this9.filters.googleAuth) {
            _this9.log(oauthMessage('google'));
            hasWarning = true;
          }
          if (_this9.filters.twitterAuth) {
            _this9.log(oauthMessage('twitter'));
            hasWarning = true;
          }

          _this9.log(_chalk2.default.green('\nYour app should now be live. To view it run\n\t' + _chalk2.default.bold('cd dist && heroku open')));

          if (hasWarning) {
            _this9.log(_chalk2.default.green('\nYou may need to address the issues mentioned above and restart the server for the app to work correctly.'));
          }

          _this9.log(_chalk2.default.yellow('\nAfter app modification run\n\t' + _chalk2.default.bold('gulp build') + '\nThen deploy with\n\t' + _chalk2.default.bold('gulp buildcontrol:heroku')));
        }
        done();
      });

      child.stdout.on('data', function (data) {
        _this9.log(data.toString());
      });
    }
  }]);

  return Generator;
}(_yeomanGenerator.Base);

exports.default = Generator;