'use strict';

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

var _stringify = require('babel-runtime/core-js/json/stringify');

var _stringify2 = _interopRequireDefault(_stringify);

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

var _regenerator2 = _interopRequireDefault(_regenerator);

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

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

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

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

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

var _createClass3 = _interopRequireDefault(_createClass2);

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

require('babel-polyfill');

var _crypto = require('crypto');

var _crypto2 = _interopRequireDefault(_crypto);

var _AgentLogger = require('./AgentLogger');

var _AgentLogger2 = _interopRequireDefault(_AgentLogger);

var _Agent = require('./Agent');

var _KmsUtils = require('../KmsUtils');

var _KmsUtils2 = _interopRequireDefault(_KmsUtils);

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

var log = _AgentLogger2.default.log();
_KmsUtils2.default.logger = log;

/**
 * representation of an event generated from a github hook SQS message
 */

var Event = exports.Event = function () {
    function Event(message, attrs) {
        (0, _classCallCheck3.default)(this, Event);

        this.attrs = attrs;
        this.payload = Event.prepareEventPayload(message, this.attrs);
        this.log = log.child({ ghEventId: this.attrs.ghEventId });
        _Agent.Agent.systemConfig.event.current = this.payload;
    }

    /**
     * list of required message attributes on SQS messages
     * @returns {[string,string,string,string,string]}
     */


    (0, _createClass3.default)(Event, null, [{
        key: 'validateMessage',


        /**
         * verify message attributes exist and check signing
         * @param message
         * @returns {{}} result attribute object
         */
        value: function () {
            var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(message) {
                var result;
                return _regenerator2.default.wrap(function _callee$(_context) {
                    while (1) {
                        switch (_context.prev = _context.next) {
                            case 0:
                                result = {};


                                Event.requiredAttributes.forEach(function (attr) {
                                    try {
                                        result[attr] = message.MessageAttributes[attr].StringValue;
                                    } catch (TypeError) {
                                        throw new Error('No Message Attribute \'' + attr + '\' in Message - discarding Event!');
                                    }
                                });

                                _context.next = 4;
                                return Event.checkEventSignature(result.ghEventSignature, message);

                            case 4:
                                if (_context.sent) {
                                    _context.next = 8;
                                    break;
                                }

                                throw new Error('Event signature mismatch - discarding Event!');

                            case 8:
                                log.info('Event signature verified. processing event..');

                            case 9:
                                return _context.abrupt('return', result);

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

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

            return validateMessage;
        }()

        /**
         * sign the event message, and check that github signature matches
         * @param signature
         * @param message
         * @returns {boolean}
         */

    }, {
        key: 'checkEventSignature',
        value: function () {
            var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(signature, message) {
                var checkEvent, calculatedSig;
                return _regenerator2.default.wrap(function _callee2$(_context2) {
                    while (1) {
                        switch (_context2.prev = _context2.next) {
                            case 0:
                                checkEvent = Event.buildCheckObject(message);

                                log.debug('eventString for signature check: ' + (0, _stringify2.default)(checkEvent));

                                _context2.t0 = _crypto2.default;
                                _context2.next = 5;
                                return _KmsUtils2.default.getDecrypted(process.env.GTM_CRYPT_GITHUB_WEBHOOK_SECRET);

                            case 5:
                                _context2.t1 = _context2.sent;
                                _context2.t2 = (0, _stringify2.default)(checkEvent);
                                _context2.t3 = _context2.t0.createHmac.call(_context2.t0, 'sha1', _context2.t1).update(_context2.t2, 'utf-8').digest('hex');
                                calculatedSig = 'sha1=' + _context2.t3;

                                if (!(calculatedSig !== signature)) {
                                    _context2.next = 11;
                                    break;
                                }

                                throw new Error('signature mismatch: ' + calculatedSig + ' !== ' + signature);

                            case 11:
                                return _context2.abrupt('return', calculatedSig === signature);

                            case 12:
                            case 'end':
                                return _context2.stop();
                        }
                    }
                }, _callee2, this);
            }));

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

            return checkEventSignature;
        }()
    }, {
        key: 'buildCheckObject',
        value: function buildCheckObject(message) {
            return {
                id: message.MessageAttributes.ghEventId.StringValue,
                body: message.Body,
                messageAttributes: {
                    ghEventId: {
                        DataType: 'String',
                        StringValue: message.MessageAttributes.ghEventId.StringValue
                    },
                    ghEventType: {
                        DataType: 'String',
                        StringValue: message.MessageAttributes.ghEventType.StringValue
                    },
                    ghTaskConfig: {
                        DataType: 'String',
                        StringValue: message.MessageAttributes.ghTaskConfig.StringValue
                    },
                    ghAgentGroup: {
                        DataType: 'String',
                        StringValue: message.MessageAttributes.ghAgentGroup.StringValue
                    }
                }
            };
        }

        /**
         * create eventData object from message body, and attach message attributes
         * @param message
         * @param attrs
         */

    }, {
        key: 'prepareEventPayload',
        value: function prepareEventPayload(message, attrs) {
            var payload = JSON.parse(message.Body);
            payload.ghEventId = attrs.ghEventId;
            payload.ghEventType = attrs.ghEventType;
            payload.ghTaskConfig = JSON.parse(attrs.ghTaskConfig);
            payload.ghAgentGroup = attrs.ghAgentGroup;
            payload.ghEventSignature = attrs.ghEventSignature;
            payload.MessageHandle = message.ReceiptHandle;

            return payload;
        }
    }, {
        key: 'requiredAttributes',
        get: function get() {
            return ['ghEventId', 'ghEventType', 'ghAgentGroup', 'ghTaskConfig', 'ghEventSignature'];
        }
    }]);
    return Event;
}();