(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.parsePathLists = exports.parsePath = void 0;
    var viewModelParseWatchCache = {};
    function parsePath(f, parseThis) {
        var str = f.toString().trim();
        str = str.split("\n").filter(function (s) { return !/^\/\//.test(s.trim()); }).join("\n");
        var key = (parseThis === undefined ? "un:" : (parseThis ? "_this:" : "_noThis:")) + str;
        var px1 = viewModelParseWatchCache[key];
        if (px1) {
            return px1;
        }
        if (str.endsWith("}")) {
            str = str.substr(0, str.length - 1);
        }
        if (str.startsWith("function (")) {
            str = str.substr("function (".length);
        }
        if (str.startsWith("function(")) {
            str = str.substr("function(".length);
        }
        str = str.trim();
        var index = str.indexOf(")");
        var commaIndex = str.indexOf(",");
        if (commaIndex !== -1 && commaIndex < index) {
            index = commaIndex;
        }
        var isThis = parseThis === undefined ? (index === 0 || parseThis) : parseThis;
        var p = (isThis ? "(\\_this|this)" : (str.substr(0, index) || "")).trim();
        /**
         * This is the case when there is no parameter to check and there `parseThis` is false
         */
        if (p.length === 0) {
            var empty = [];
            viewModelParseWatchCache[key] = empty;
            return empty;
        }
        str = str.substr(index + 1);
        var regExp = "(?:(\\b" + p + ")(?:(\\.[a-zA-Z_][a-zA-Z_0-9]*)+)\\s?(?:(\\(|\\=\\=\\=|\\=\\=|\\=)?))";
        var re = new RegExp(regExp, "gi");
        var path = [];
        var ms = str.replace(re, function (m) {
            // console.log(`m: ${m}`);
            var px = m;
            if (px.startsWith("this.")) {
                if (parseThis !== true) {
                    px = px.substr(5);
                }
            }
            else if (px.startsWith("_this.")) {
                if (parseThis !== true) {
                    px = px.substr(6);
                }
                else {
                    // need to convert _this to this
                    px = px.substr(1);
                }
            }
            else {
                px = px.substr(p.length + 1);
            }
            // console.log(px);
            if (!path.find(function (y) { return y === px; })) {
                path.push(px);
            }
            path = path.filter(function (f1) { return f1.endsWith("==") || !(f1.endsWith("(") || f1.endsWith("=")); });
            path = path.map(function (px2) { return px2.endsWith("===") ? px2.substr(0, px2.length - 3) :
                (px2.endsWith("==") ? px2.substr(0, px2.length - 2) : px2); })
                .map(function (px2) { return px2.trim(); });
            return m;
        });
        path = path.sort(function (a, b) { return b.localeCompare(a); });
        var duplicates = path;
        path = [];
        var _loop_1 = function (iterator) {
            if (path.find(function (px2) { return px2 === iterator; })) {
                return "continue";
            }
            path.push(iterator);
        };
        for (var _i = 0, duplicates_1 = duplicates; _i < duplicates_1.length; _i++) {
            var iterator = duplicates_1[_i];
            _loop_1(iterator);
        }
        var rp = [];
        var _loop_2 = function (rpItem) {
            if (rp.find(function (x) { return x.startsWith(rpItem); })) {
                return "continue";
            }
            rp.push(rpItem);
        };
        for (var _a = 0, path_1 = path; _a < path_1.length; _a++) {
            var rpItem = path_1[_a];
            _loop_2(rpItem);
        }
        // tslint:disable-next-line: no-console
        // console.log(`Watching: ${path.join(", ")}`);
        var pl = path.map(function (p1) { return p1.split("."); });
        viewModelParseWatchCache[key] = pl;
        return pl;
    }
    exports.parsePath = parsePath;
    var viewModelParseWatchCache2 = {};
    function parsePathLists(f) {
        var str = f.toString().trim();
        var key = str;
        var px1 = viewModelParseWatchCache2[key];
        if (px1) {
            return px1;
        }
        // str = str.split("\n").filter((s) => !/^\/\//.test(s.trim())).join("\n");
        // if (str.endsWith("}")) {
        //     str = str.substr(0, str.length - 1);
        // }
        // if (str.startsWith("function (")) {
        //     str = str.substr("function (".length);
        // }
        // if (str.startsWith("function(")) {
        //     str = str.substr("function(".length);
        // }
        // str = str.trim();
        var pl = {
            pathList: parsePath(str, false),
            thisPath: parsePath(str, true),
            combined: []
        };
        if (pl.thisPath.length && pl.pathList.length) {
            // we need to combine this
            // pl.combinedPathList =
            pl.combined = pl.thisPath
                .map(function (x) {
                x[0] = "t";
                x.splice(0, 0, "this");
                return x;
            })
                .concat(pl.pathList.map(function (x) {
                x.splice(0, 0, "this", "x");
                return x;
            }));
            pl.thisPath = [];
            pl.pathList = [];
        }
        viewModelParseWatchCache2[key] = pl;
        return pl;
    }
    exports.parsePathLists = parsePathLists;
});
//# sourceMappingURL=ExpressionParser.js.map