import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { ApiRoot } from 'dotcms-js/dotcms-js';
import { Verify } from '../../validation/Verify';
import { LoggerService } from 'dotcms-js/dotcms-js';
import { HttpCode } from 'dotcms-js/dotcms-js';
var TreeNode = (function () {
    function TreeNode(parent, key) {
        this._p = parent;
        this._k = key;
        this._loading = null;
        this._loaded = false;
    }
    TreeNode.prototype.$addAllFromJson = function (key, childJson) {
        var cNode = this.$child(key);
        if (Verify.isString(childJson)) {
            cNode._value = childJson;
        }
        else {
            Object.keys(childJson).forEach(function (cKey) {
                cNode.$addAllFromJson(cKey, childJson[cKey]);
            });
        }
        cNode._loaded = true;
    };
    TreeNode.prototype.$isLeaf = function () {
        return this._value !== undefined;
    };
    TreeNode.prototype.$isLoaded = function () {
        return this._p == null ? false : this._loaded || this._p.$isLoaded();
    };
    TreeNode.prototype.$isLoading = function () {
        return this._p == null ? false : this._loading != null || this._p.$isLoading();
    };
    TreeNode.prototype.$markAsLoaded = function () {
        this._loaded = true;
        this.$children().forEach(function (child) { return child.$markAsLoaded(); });
    };
    TreeNode.prototype.$markAsLoading = function (promise) {
        this._loaded = false;
        this._loading = promise;
        this.$children().forEach(function (child) { return child.$markAsLoading(promise); });
    };
    TreeNode.prototype.$children = function () {
        var _this = this;
        return Object.keys(this).filter(function (key) { return key[0] !== '_'; }).map(function (cKey) { return _this[cKey]; });
    };
    TreeNode.prototype.$child = function (cKey) {
        var child;
        child = this[cKey];
        if (child == null) {
            child = new TreeNode(this, cKey);
            child._loading = this._loading;
            this[cKey] = child;
        }
        return child;
    };
    TreeNode.prototype.$descendant = function (path) {
        var cKey = path[0];
        var child = this.$child(cKey);
        if (path.length > 1) {
            child = child.$descendant(path.slice(1));
        }
        return child;
    };
    TreeNode.prototype.$isPathLoaded = function (path) {
        return this.$descendant(path).$isLoaded();
    };
    return TreeNode;
}());
export { TreeNode };
var I18nService = (function () {
    function I18nService(apiRoot, http, loggerService) {
        this.loggerService = loggerService;
        this._http = http;
        this._apiRoot = apiRoot;
        this._baseUrl = apiRoot.baseUrl + 'api/v1/system/i18n';
        this.root = new TreeNode(null, 'root');
    }
    I18nService.prototype.makeRequest = function (url) {
        var opts = this._apiRoot.getDefaultRequestOptions();
        return this._http.get(this._baseUrl + '/' + url, opts).map(function (res) {
            return res.json();
        });
    };
    I18nService.prototype.get = function (msgKey, defaultValue) {
        if (defaultValue === void 0) { defaultValue = '-error loading resource-'; }
        return this.getForLocale(this._apiRoot.authUser.locale, msgKey, true, defaultValue);
    };
    I18nService.prototype.getForLocale = function (locale, msgKey, forceText, defaultValue) {
        var _this = this;
        if (forceText === void 0) { forceText = true; }
        if (defaultValue === void 0) { defaultValue = '-error loading resource-'; }
        msgKey = locale + '.' + msgKey;
        var path = msgKey.split('.');
        var cNode = this.root.$descendant(path);
        if (!cNode.$isLoaded() && !cNode.$isLoading()) {
            var promise = new Promise(function (resolve, reject) {
                _this.makeRequest(path.join('/'))
                    .catch(function (err, source) {
                    if (err && err.status === HttpCode.NOT_FOUND) {
                        _this.loggerService.debug('Missing Resource: \'', msgKey, '\'');
                    }
                    else {
                        _this.loggerService.debug('I18n', 'Failed:: ', msgKey, '=', cNode, 'error:', err);
                    }
                    return Observable.create(function (obs) {
                        obs.next(defaultValue);
                    });
                })
                    .subscribe(function (jsonVal) {
                    cNode._p.$addAllFromJson(cNode._k, jsonVal);
                    cNode.$markAsLoaded();
                    resolve(cNode);
                });
            });
            cNode.$markAsLoading(promise);
        }
        return Observable.defer(function () {
            return Observable.create(function (obs) {
                if (cNode._loading == null) {
                    _this.loggerService.debug('I18n', 'Failed: ', msgKey, '=', cNode);
                    obs.next('-I18nLoadFailed-');
                    obs.complete();
                }
                else {
                    cNode._loading.then(function () {
                        var v;
                        if (!cNode.$isLeaf()) {
                            if (forceText) {
                                v = defaultValue;
                            }
                            else {
                                v = cNode;
                            }
                        }
                        else {
                            v = cNode._value;
                        }
                        obs.next(v);
                        obs.complete();
                    });
                }
            });
        });
    };
    return I18nService;
}());
export { I18nService };
I18nService.decorators = [
    { type: Injectable },
];
/** @nocollapse */
I18nService.ctorParameters = function () { return [
    { type: ApiRoot, },
    { type: Http, },
    { type: LoggerService, },
]; };
//# sourceMappingURL=I18n.js.map