'use strict';

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

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var generateConf = exports.generateConf = function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(preloadedRules) {
        var propertyRules, propertyName, propertyVersion, defaultRule, ruleConf, luaVarMap, luaValueMap, utilFunctions, akamaiFunctions, luaConf;
        return regeneratorRuntime.wrap(function _callee$(_context) {
            while (1) {
                switch (_context.prev = _context.next) {
                    case 0:
                        if (!preloadedRules) {
                            _context.next = 4;
                            break;
                        }

                        _context.t0 = preloadedRules;
                        _context.next = 7;
                        break;

                    case 4:
                        _context.next = 6;
                        return getPropertyRules();

                    case 6:
                        _context.t0 = _context.sent;

                    case 7:
                        propertyRules = _context.t0;
                        propertyName = propertyRules.propertyName;
                        propertyVersion = propertyRules.propertyVersion;
                        _context.next = 12;
                        return console.log('processing rules for property ' + propertyName + ' v' + propertyVersion);

                    case 12:
                        defaultRule = new _rule.Rule(propertyRules.rules.name, propertyRules.rules.criteria, propertyRules.rules.criteriaMustSatisfy, propertyRules.rules.behaviors, propertyRules.rules.children, skipBehaviors, valueMap, 0 // depth starts at 0
                        );
                        ruleConf = '\n-- ### Property Rules : generated from ';

                        ruleConf += config.localPapiJsonPath ? 'local: ' + config.localPapiJsonPath : 'api: ' + getPapiUrl() + ' ###';
                        ruleConf += '\n' + defaultRule.process() + '\n';

                        // dynamically construct a lua mapping function based on declared property vars
                        luaVarMap = buildLuaVarMap(propertyRules);

                        // translate the js valueMap into a lua map - used for host header translation in origin behavior

                        luaValueMap = buildLuaValueMap(valueMap);

                        // load some utils and vars

                        utilFunctions = _fs2.default.readFileSync(__dirname + '/../../lua/utils.lua', 'utf8');

                        // load some utils and vars

                        akamaiFunctions = _fs2.default.readFileSync(__dirname + '/../../lua/akamaiFunctions.lua', 'utf8');

                        // concat all lua

                        luaConf = utilFunctions + luaValueMap + luaVarMap + akamaiFunctions + ruleConf + 'finalActions()';

                        // create empty file and write

                        _fs2.default.closeSync(_fs2.default.openSync(config.outPutFile, 'w'));
                        _fs2.default.writeFileSync(config.outPutFile, luaConf, 'utf8');

                        _context.next = 25;
                        return console.log('processing completed for property ' + propertyName + ' v' + propertyVersion);

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

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

var getPropertyRules = function () {
    var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
        return regeneratorRuntime.wrap(function _callee2$(_context2) {
            while (1) {
                switch (_context2.prev = _context2.next) {
                    case 0:
                        return _context2.abrupt('return', new Promise(function (resolve, reject) {
                            if (config.localPapiJsonPath) {
                                // load local
                                console.log('loading local rules from: ' + config.localPapiJsonPath + '\n');
                                _fs2.default.readFile(config.localPapiJsonPath, function (err, rules) {
                                    if (err) {
                                        return reject(err);
                                    }
                                    return resolve(JSON.parse(rules));
                                });
                            } else {

                                // or call papi
                                var papiUrl = getPapiUrl();
                                console.log('loading rules from papi url: ' + papiUrl + '\n');

                                config.edgegrid.auth({
                                    path: papiUrl,
                                    method: 'GET'
                                }).send(function (error, response, body) {
                                    console.debug('akamai api response body: %o', body);
                                    return resolve(JSON.parse(body));
                                });
                            }
                        }));

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

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

exports.setApiConfig = setApiConfig;
exports.setLocalConfig = setLocalConfig;
exports.setValueMap = setValueMap;
exports.setSkipBehaviors = setSkipBehaviors;

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _rule = require('./rule.js');

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

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var config = {};

process.on('unhandledRejection', function (reason, p) {
    console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
    // application specific logging, throwing an error, or other logic here
});

function setApiConfig(edgegrid, contractId, groupId, propertyId, propertyVersion, outputFile) {
    config = {};
    config.edgegrid = edgegrid;
    config.contractId = contractId;
    config.groupId = groupId;
    config.propertyId = propertyId;
    config.propertyVersion = propertyVersion;
    config.outPutFile = outputFile;
    return this;
}

function setLocalConfig(localPapiJsonPath, outputFile) {
    config = {};
    config.localPapiJsonPath = localPapiJsonPath;
    config.outPutFile = outputFile;
    return this;
}

var valueMap = new Map([['HTTP', 'http'], ['HTTPS', 'https']]);

function setValueMap(map) {
    valueMap = new Map([].concat(_toConsumableArray(valueMap), _toConsumableArray(map)));
}

var skipBehaviors = ['webApplicationFirewall'];

function setSkipBehaviors(skip) {
    skipBehaviors = [].concat(_toConsumableArray(skipBehaviors), _toConsumableArray(skip));
}

function getPapiUrl() {
    return '/papi/v1/properties/' + config.propertyId + '/versions/' + config.propertyVersion + '/rules?contractId=' + config.contractId + '&groupId=' + config.groupId;
}

function buildLuaVarMap(propertyRules) {

    // load builtin var definitions
    var variableDefns = JSON.parse(_fs2.default.readFileSync(__dirname + '/akamai-vars.json', 'utf8'));

    // collect any pmuser declared vars for property
    if (propertyRules.rules.variables.length > 0) {
        propertyRules.rules.variables.forEach(function (pmUserVar) {
            variableDefns.push({
                key: pmUserVar.name,
                lua: '"' + pmUserVar.value + '"',
                comment: pmUserVar.description
            });
        });
    }

    var lua = '\n\n-- ### Generated varMap from akamai-vars.json and property vars..\n';
    lua += 'local varMap = { }\n';
    variableDefns.forEach(function (variable) {
        lua += '-- ' + variable.comment + '\n';
        lua += 'varMap["' + variable.key + '"] = function() return ' + variable.lua + ' end\n\n';
    });

    return lua;
}

function buildLuaValueMap(valueMap) {
    var lua = '\n\n-- ### Generated valueMap from valueMap.local.json and passed in valueMap..\n';
    lua += 'local valueMap = { }\n';
    var _iteratorNormalCompletion = true;
    var _didIteratorError = false;
    var _iteratorError = undefined;

    try {
        for (var _iterator = valueMap.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
            var _step$value = _slicedToArray(_step.value, 2),
                key = _step$value[0],
                value = _step$value[1];

            lua += 'valueMap["' + key + '"] = "' + value + '"\n';
        }
    } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
    } finally {
        try {
            if (!_iteratorNormalCompletion && _iterator.return) {
                _iterator.return();
            }
        } finally {
            if (_didIteratorError) {
                throw _iteratorError;
            }
        }
    }

    return lua;
}