'use strict';

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

var _regenerator2 = _interopRequireDefault(_regenerator);

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

var _promise2 = _interopRequireDefault(_promise);

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

var _stringify2 = _interopRequireDefault(_stringify);

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

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var handler = function () {
    var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(event, context, callback) {
        var dynamo, ddb, payload;
        return _regenerator2.default.wrap(function _callee$(_context) {
            while (1) {
                switch (_context.prev = _context.next) {
                    case 0:
                        if (process.env.IAM_ENABLED) {
                            AWS.config.update({
                                httpOptions: {
                                    agent: PROXY_AGENT(process.env.AWS_PROXY)
                                }
                            });
                        }

                        dynamo = void 0;

                        if (process.env.GTM_DYNAMO_VPCE) {
                            console.log('Configuring DynamoDB to use VPC Endpoint');
                            dynamo = new AWS.DynamoDB({
                                httpOptions: {
                                    agent: new HTTPS.Agent()
                                }
                            });
                        } else {
                            console.log('Configuring DynamoDB to use Global AWS Config');
                            dynamo = new AWS.DynamoDB();
                        }

                        ddb = new AWS.DynamoDB.DocumentClient({
                            convertEmptyValues: true,
                            service: dynamo
                        });


                        console.log('Recording Metrics...');

                        payload = new Buffer(event.awslogs.data, 'base64');

                        zlib.gunzip(payload, function (err, res) {
                            if (err) {
                                console.log(err);
                                return callback(err);
                            }
                            var payload = JSON.parse(res.toString('utf8'));
                            console.log('Decoded Payload:', (0, _stringify2.default)(payload));

                            var EVENTS_TABLE = process.env.GTM_DYNAMO_TABLE_EVENTS;

                            var promises = [];

                            payload.logEvents.forEach(function (evt) {
                                var msg = void 0;
                                var isObj = true;
                                try {
                                    msg = JSON.parse(evt.message);
                                } catch (e) {
                                    msg = evt.message;
                                    console.error('Unable to Parse Event Payload: ' + msg);
                                    isObj = false;
                                }

                                /***
                                 * Capture event summary data
                                 * gtmEvents table schema: ghEventId, startTime, eventDuration, endTime,
                                 * tasks, eventResult, repo, eventUrl, pullTitle, pullNumber, sha, eventUser
                                 */
                                if (isObj) {
                                    var updateParams = void 0;

                                    if (msg.resultType === 'START') {
                                        console.log('Recording Event Start: ' + msg.ghEventId + '..');
                                        updateParams = {
                                            TableName: EVENTS_TABLE,
                                            Key: {
                                                ghEventId: msg.ghEventId
                                            },
                                            UpdateExpression: 'set startTime = :startTime, repo = :repo, eventUrl = :eventUrl, tasks = :tasks, ' + 'endTime = :endTime, eventDuration = :eventDuration, failed = :failed, ' + 'pullTitle = :pullTitle, pullNumber = :pullNumber, sha = :sha, eventUser = :eventUser',
                                            ConditionExpression: 'attribute_not_exists(ghEventId) OR ghEventId = :ghEventId',
                                            ExpressionAttributeValues: {
                                                ':ghEventId': msg.ghEventId,
                                                ':startTime': msg.time,
                                                ':repo': msg.repo,
                                                ':eventUrl': msg.url,
                                                ':tasks': [],
                                                ':endTime': '',
                                                ':eventDuration': '',
                                                ':failed': '',
                                                ':pullTitle': msg.pullTitle,
                                                ':pullNumber': msg.pullNumber,
                                                ':sha': msg.sha,
                                                ':eventUser': msg.eventUser
                                            },
                                            ReturnValues: 'UPDATED_NEW'
                                        };
                                    }

                                    if (msg.resultType === 'TASK') {
                                        console.log('Recording Event Progress: ' + msg.ghEventId + '..');

                                        var task = {
                                            executor: msg.executor,
                                            context: msg.context,
                                            duration: msg.duration,
                                            failed: msg.failed,
                                            time: msg.time
                                        };

                                        updateParams = {
                                            TableName: EVENTS_TABLE,
                                            Key: {
                                                ghEventId: msg.ghEventId
                                            },
                                            UpdateExpression: 'set tasks = list_append(tasks, :task)',
                                            ConditionExpression: 'attribute_not_exists(ghEventId) OR ghEventId = :ghEventId',
                                            ExpressionAttributeValues: {
                                                ':ghEventId': msg.ghEventId,
                                                ':task': [task]
                                            },
                                            ReturnValues: 'UPDATED_NEW'
                                        };
                                    }

                                    if (msg.resultType === 'EVENT') {
                                        console.log('Recording Event Completion: ' + msg.ghEventId + '..');

                                        updateParams = {
                                            TableName: EVENTS_TABLE,
                                            Key: {
                                                ghEventId: msg.ghEventId
                                            },
                                            UpdateExpression: 'set endTime = :endTime, eventDuration = :eventDuration, failed = :failed',
                                            ConditionExpression: 'attribute_not_exists(ghEventId) OR ghEventId = :ghEventId',
                                            ExpressionAttributeValues: {
                                                ':ghEventId': msg.ghEventId,
                                                ':endTime': msg.time,
                                                ':eventDuration': msg.duration,
                                                ':failed': msg.failed
                                            },
                                            ReturnValues: 'UPDATED_NEW'
                                        };
                                    }

                                    if (updateParams) {
                                        promises.push(ddb.update(updateParams).promise());
                                    }
                                }
                            });

                            _promise2.default.all(promises).then(function () {
                                callback(null, 'Successfully processed ' + payload.logEvents.length + ' log events.');
                            });
                        });

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

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

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

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

var AWS = require('aws-sdk');
var HTTPS = require('https');
var PROXY_AGENT = require('https-proxy-agent');

AWS.config.update({ region: process.env.GTM_AWS_REGION });

var zlib = require('zlib');

module.exports = {
    handler: handler
};