'use strict';

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

var _regenerator = require('babel-runtime/regenerator');

var _regenerator2 = _interopRequireDefault(_regenerator);

var _promise = require('babel-runtime/core-js/promise');

var _promise2 = _interopRequireDefault(_promise);

var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');

var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

require('source-map-support/register');

var _jenkins = require('jenkins');

var _jenkins2 = _interopRequireDefault(_jenkins);

var _Executor2 = require('../agent/Executor');

var _AgentUtils = require('../agent/AgentUtils');

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

/**
 * Sample .githubTaskManager.json task config/
 *
 * see: https://github.com/zotoio/github-task-manager/wiki/Structure-of-.githubTaskManager.json
 *
 * {
        "executor": "Jenkins",
        "context": "Build and deploy",
        "options": {
          "jobName": "JENKINS_JOBNAME",
          "parameters": {
            "ENVIRONMENT" : "env_dev"
        }
    }
 */

var ExecutorJenkins = exports.ExecutorJenkins = function (_Executor) {
    (0, _inherits3.default)(ExecutorJenkins, _Executor);

    function ExecutorJenkins(eventData, log) {
        (0, _classCallCheck3.default)(this, ExecutorJenkins);

        var _this = (0, _possibleConstructorReturn3.default)(this, (ExecutorJenkins.__proto__ || (0, _getPrototypeOf2.default)(ExecutorJenkins)).call(this, eventData, log));

        _this.log = log;
        _this.options = _this.getOptions();

        // If set, this will return bool:true, else bool:false
        var useCsrf = _this.options.GTM_JENKINS_CSRF === 'true';

        _this.jenkins = (0, _jenkins2.default)({
            baseUrl: _AgentUtils.AgentUtils.formatBasicAuth(_this.options.GTM_JENKINS_USER, _this.options.GTM_JENKINS_TOKEN, _this.options.GTM_JENKINS_URL),
            crumbIssuer: useCsrf,
            promisify: true
        });
        return _this;
    }

    (0, _createClass3.default)(ExecutorJenkins, [{
        key: 'waitForBuildToExist',
        value: function () {
            var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(buildName, buildNumber) {
                var _this2 = this;

                var log;
                return _regenerator2.default.wrap(function _callee3$(_context3) {
                    while (1) {
                        switch (_context3.prev = _context3.next) {
                            case 0:
                                log = this.log;
                                return _context3.abrupt('return', new _promise2.default(function () {
                                    var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(resolve, reject) {
                                        var exists, maxRetries, tries;
                                        return _regenerator2.default.wrap(function _callee2$(_context2) {
                                            while (1) {
                                                switch (_context2.prev = _context2.next) {
                                                    case 0:
                                                        exists = false;
                                                        maxRetries = 600;
                                                        tries = 0;

                                                    case 3:
                                                        if (!(!exists && tries++ < maxRetries)) {
                                                            _context2.next = 9;
                                                            break;
                                                        }

                                                        _context2.next = 6;
                                                        return _this2.jenkins.build.get(buildName, buildNumber).then(function () {
                                                            log.info('Build ' + buildName + ' #' + buildNumber + ' Started!');
                                                            return true;
                                                        }, (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() {
                                                            return _regenerator2.default.wrap(function _callee$(_context) {
                                                                while (1) {
                                                                    switch (_context.prev = _context.next) {
                                                                        case 0:
                                                                            log.debug('Build ' + buildName + ' #' + buildNumber + ' Hasn\'t Started: ' + tries);
                                                                            _context.next = 3;
                                                                            return _AgentUtils.AgentUtils.timeout(10000);

                                                                        case 3:
                                                                            return _context.abrupt('return', false);

                                                                        case 4:
                                                                        case 'end':
                                                                            return _context.stop();
                                                                    }
                                                                }
                                                            }, _callee, this);
                                                        })));

                                                    case 6:
                                                        exists = _context2.sent;
                                                        _context2.next = 3;
                                                        break;

                                                    case 9:
                                                        exists ? resolve(true) : reject();

                                                    case 10:
                                                    case 'end':
                                                        return _context2.stop();
                                                }
                                            }
                                        }, _callee2, _this2);
                                    }));

                                    return function (_x3, _x4) {
                                        return _ref2.apply(this, arguments);
                                    };
                                }()));

                            case 2:
                            case 'end':
                                return _context3.stop();
                        }
                    }
                }, _callee3, this);
            }));

            function waitForBuildToExist(_x, _x2) {
                return _ref.apply(this, arguments);
            }

            return waitForBuildToExist;
        }()
    }, {
        key: 'waitForBuild',
        value: function () {
            var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(buildName, buildNumber) {
                var log, buildDict, tries;
                return _regenerator2.default.wrap(function _callee4$(_context4) {
                    while (1) {
                        switch (_context4.prev = _context4.next) {
                            case 0:
                                log = this.log;
                                _context4.next = 3;
                                return this.jenkins.build.get(buildName, buildNumber).then(function (data) {
                                    return data;
                                });

                            case 3:
                                buildDict = _context4.sent;
                                tries = 1;

                            case 5:
                                if (!(buildDict.result === null)) {
                                    _context4.next = 13;
                                    break;
                                }

                                _context4.next = 8;
                                return _AgentUtils.AgentUtils.timeout(5000);

                            case 8:
                                _context4.next = 10;
                                return this.jenkins.build.get(buildName, buildNumber).then(function (data) {
                                    log.debug('Waiting for Build \'' + buildName + '\' to Finish: ' + tries++);
                                    return data;
                                });

                            case 10:
                                buildDict = _context4.sent;
                                _context4.next = 5;
                                break;

                            case 13:
                                log.info('Build Finished: ' + buildName + ' #' + buildNumber + ' - ' + buildDict.result);
                                return _context4.abrupt('return', buildDict);

                            case 15:
                            case 'end':
                                return _context4.stop();
                        }
                    }
                }, _callee4, this);
            }));

            function waitForBuild(_x5, _x6) {
                return _ref4.apply(this, arguments);
            }

            return waitForBuild;
        }()
    }, {
        key: 'buildNumberfromQueue',
        value: function () {
            var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(queueId) {
                var log, queueData;
                return _regenerator2.default.wrap(function _callee5$(_context5) {
                    while (1) {
                        switch (_context5.prev = _context5.next) {
                            case 0:
                                log = this.log;
                                _context5.next = 3;
                                return this.jenkins.queue.item(queueId).then(function (data) {
                                    return data;
                                });

                            case 3:
                                queueData = _context5.sent;

                            case 4:
                                if (queueData.executable) {
                                    _context5.next = 13;
                                    break;
                                }

                                try {
                                    log.info('Build Not Ready: ' + queueData.why);
                                } catch (error) {
                                    log.warn('Build Not Ready: No Reason Provided. Retrying in 3 seconds...');
                                }
                                _context5.next = 8;
                                return _AgentUtils.AgentUtils.timeout(3000);

                            case 8:
                                _context5.next = 10;
                                return this.jenkins.queue.item(queueId).then(function (data) {
                                    return data;
                                });

                            case 10:
                                queueData = _context5.sent;
                                _context5.next = 4;
                                break;

                            case 13:
                                return _context5.abrupt('return', queueData.executable.number);

                            case 14:
                            case 'end':
                                return _context5.stop();
                        }
                    }
                }, _callee5, this);
            }));

            function buildNumberfromQueue(_x7) {
                return _ref5.apply(this, arguments);
            }

            return buildNumberfromQueue;
        }()
    }, {
        key: 'executeTask',
        value: function () {
            var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(task) {
                var log, jobName, buildParams, configuration, queueNumber, buildNumber, buildExists, result, resultBool;
                return _regenerator2.default.wrap(function _callee6$(_context6) {
                    while (1) {
                        switch (_context6.prev = _context6.next) {
                            case 0:
                                log = this.log;
                                jobName = task.options.jobName || null;
                                buildParams = task.options.parameters || null;
                                configuration = {};

                                if (!(jobName == null)) {
                                    _context6.next = 11;
                                    break;
                                }

                                _context6.next = 7;
                                return _AgentUtils.AgentUtils.timeout(4000);

                            case 7:
                                task.results = {
                                    passed: false,
                                    url: this.options.GTM_JENKINS_URL,
                                    message: 'Required Parameter \'Job Name\' not Specified'
                                };
                                return _context6.abrupt('return', _promise2.default.reject(task));

                            case 11:
                                configuration.name = jobName;

                            case 12:

                                if (buildParams != null && buildParams != []) configuration.parameters = buildParams;

                                log.info('Starting Jenkins Job: ' + jobName);
                                // TODO: Check if Job Exists
                                _context6.next = 16;
                                return this.jenkins.job.build(configuration);

                            case 16:
                                queueNumber = _context6.sent;
                                _context6.next = 19;
                                return this.buildNumberfromQueue(queueNumber);

                            case 19:
                                buildNumber = _context6.sent;
                                _context6.next = 22;
                                return this.waitForBuildToExist(jobName, buildNumber);

                            case 22:
                                buildExists = _context6.sent;

                                console.debug(buildExists);
                                _context6.next = 26;
                                return this.waitForBuild(jobName, buildNumber);

                            case 26:
                                result = _context6.sent;
                                resultBool = result.result === 'SUCCESS';


                                task.results = {
                                    passed: resultBool,
                                    url: result.url,
                                    message: jobName + ' #' + buildNumber + ' - ' + result.result,
                                    details: 'Job \'' + jobName + ' #' + buildNumber + '\' Finished: ' + result.result,
                                    meta: {
                                        jobName: jobName,
                                        buildNumber: buildNumber
                                    }
                                };

                                return _context6.abrupt('return', resultBool ? _promise2.default.resolve(task) : _promise2.default.reject(task));

                            case 30:
                            case 'end':
                                return _context6.stop();
                        }
                    }
                }, _callee6, this);
            }));

            function executeTask(_x8) {
                return _ref6.apply(this, arguments);
            }

            return executeTask;
        }()
    }]);
    return ExecutorJenkins;
}(_Executor2.Executor);

_Executor2.Executor.register('Jenkins', ExecutorJenkins);