var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
(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", "../core/StringHelper", "../di/RegisterSingleton"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var StringHelper_1 = require("../core/StringHelper");
    var RegisterSingleton_1 = require("../di/RegisterSingleton");
    exports.dateFormatISORegEx = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/;
    exports.dateFormatMSRegEx = /^\/Date\((d|-|.*)\)[\/|\\]$/;
    var timeZoneDiff = (new Date()).getTimezoneOffset();
    var JsonService = /** @class */ (function () {
        function JsonService() {
            this.options = {
                indent: 2,
                namingStrategy: "none",
                dateConverter: [
                    {
                        regex: exports.dateFormatISORegEx,
                        valueConverter: {
                            fromSource: function (v) {
                                var d = new Date(v);
                                // if (/z$/i.test(v)) {
                                //     d.setMinutes( d.getMinutes() - timeZoneDiff );
                                // }
                                return d;
                            },
                            fromTarget: function (v) {
                                return v.toISOString();
                            }
                        }
                    }, {
                        regex: exports.dateFormatMSRegEx,
                        valueConverter: {
                            fromSource: function (v) {
                                var a = exports.dateFormatMSRegEx.exec(v);
                                var b = a[1].split(/[-+,.]/);
                                return new Date(b[0] ? +b[0] : 0 - +b[1]);
                            },
                            fromTarget: function (v) {
                                return v.toISOString();
                            }
                        }
                    }
                ]
            };
        }
        JsonService.prototype.transformKeys = function (t, v) {
            var _this = this;
            if (!v) {
                return v;
            }
            if (typeof v !== "object") {
                return v;
            }
            if (v instanceof Date) {
                return v;
            }
            if (typeof v === "object" && v.length !== undefined && typeof v.length === "number") {
                var a = v;
                if (a.map) {
                    return a.map(function (x) { return _this.transformKeys(t, x); });
                }
                var ra = [];
                for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
                    var iterator = a_1[_i];
                    ra.push(this.transformKeys(t, iterator));
                }
                return ra;
            }
            var r = {};
            for (var key in v) {
                if (v.hasOwnProperty(key)) {
                    var element = v[key];
                    r[t(key)] = this.transformKeys(t, element);
                }
            }
            return r;
        };
        JsonService.prototype.parse = function (text, options) {
            var _a = __assign(__assign({}, this.options), options), dateConverter = _a.dateConverter, namingStrategy = _a.namingStrategy;
            var result = JSON.parse(text, function (key, value) {
                // transform date...
                if (typeof value === "string") {
                    for (var _i = 0, dateConverter_1 = dateConverter; _i < dateConverter_1.length; _i++) {
                        var iterator = dateConverter_1[_i];
                        var a = iterator.regex.test(value);
                        if (a) {
                            var dv = iterator.valueConverter.fromSource(value);
                            return dv;
                        }
                    }
                }
                return value;
            });
            switch (namingStrategy) {
                case "hyphen":
                    return this.transformKeys(StringHelper_1.StringHelper.fromHyphenToCamel, result);
                case "underscore":
                    return this.transformKeys(StringHelper_1.StringHelper.fromUnderscoreToCamel, result);
                case "pascal":
                    return this.transformKeys(StringHelper_1.StringHelper.fromPascalToCamel, result);
            }
            return result;
        };
        JsonService.prototype.stringify = function (v, options) {
            var _a = __assign(__assign({}, this.options), options), namingStrategy = _a.namingStrategy, dateConverter = _a.dateConverter, indent = _a.indent;
            switch (namingStrategy) {
                case "hyphen":
                    v = this.transformKeys(StringHelper_1.StringHelper.fromCamelToHyphen, v);
                    break;
                case "underscore":
                    v = this.transformKeys(StringHelper_1.StringHelper.fromCamelToUnderscore, v);
                    break;
                case "pascal":
                    v = this.transformKeys(StringHelper_1.StringHelper.fromCamelToPascal, v);
                    break;
            }
            return JSON.stringify(v, function (key, value) {
                if (key && /^\_\$\_/.test(key)) {
                    return undefined;
                }
                if (dateConverter && (value instanceof Date)) {
                    return dateConverter[0].valueConverter.fromTarget(value);
                }
                return value;
            }, indent);
        };
        JsonService = __decorate([
            RegisterSingleton_1.RegisterSingleton
        ], JsonService);
        return JsonService;
    }());
    exports.JsonService = JsonService;
});
//# sourceMappingURL=JsonService.js.map