"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    createTree: function() {
        return createTree;
    },
    default: function() {
        return bbob;
    }
});
var _parser = require("@bbob/parser");
var _utils = require("./utils.js");
var _errors = require("./errors.js");
function _extends() {
    _extends = Object.assign || function(target) {
        for(var i = 1; i < arguments.length; i++){
            var source = arguments[i];
            for(var key in source){
                if (Object.prototype.hasOwnProperty.call(source, key)) {
                    target[key] = source[key];
                }
            }
        }
        return target;
    };
    return _extends.apply(this, arguments);
}
function createTree(tree, options) {
    var extendedTree = tree;
    extendedTree.messages = [].concat(extendedTree.messages || []);
    extendedTree.options = _extends({}, options, extendedTree.options);
    extendedTree.walk = function walkNodes(cb) {
        return (0, _utils.iterate)(this, cb);
    };
    extendedTree.match = function matchNodes(expr, cb) {
        return (0, _utils.match)(this, expr, cb);
    };
    return extendedTree;
}
function bbob(plugs) {
    var plugins = typeof plugs === "function" ? [
        plugs
    ] : plugs || [];
    var mockRender = function() {
        return "";
    };
    return {
        process: function process(input, opts) {
            var options = opts || {
                skipParse: false,
                parser: _parser.parse,
                render: mockRender,
                data: null
            };
            var parseFn = options.parser || _parser.parse;
            var renderFn = options.render;
            var data = options.data || null;
            if (typeof parseFn !== "function") {
                throw new Error(_errors.C1);
            }
            // raw tree before modification with plugins
            var raw = options.skipParse && Array.isArray(input) ? input : parseFn(input, options);
            var tree = options.skipParse && Array.isArray(input) ? createTree(input || [], options) : createTree(raw, options);
            for(var idx = 0; idx < plugins.length; idx++){
                var plugin = plugins[idx];
                if (typeof plugin === "function" && renderFn) {
                    var newTree = plugin(tree, {
                        parse: parseFn,
                        render: renderFn,
                        iterate: _utils.iterate,
                        data: data
                    });
                    tree = createTree(newTree || tree, options);
                }
            }
            return {
                get html () {
                    if (typeof renderFn !== "function") {
                        throw new Error(_errors.C2);
                    }
                    return renderFn(tree, tree.options);
                },
                tree: tree,
                raw: raw,
                messages: tree.messages
            };
        }
    };
}
