/* Copyright CloudLinux Zug GmbH 2010-2017 All Rights Reserved
 *
 * Licensed under CLOUD LINUX LICENSE AGREEMENT
 * http://cloudlinux.com/docs/LICENSE.TXT
 */

import {Injectable} from "@angular/core";
import {TranslateParser} from "@ngx-translate/core";
import {TranslateClass} from "./pipes/translate";

@Injectable()
export class TranslateLocaleParser extends TranslateParser {
    templates = [/\{\{(.*?)\}\}/g, /\%\((.*?)\)s/g, /{([^{}]*)}/g];
    translateClass = new TranslateClass();

    public interpolate(expr: string, params?: any): string {
        if (typeof expr !== 'string' || !params) {
            return expr;
        }

        let translatedParams = this.translateParams(params || {});
        return this.templates.reduce((str, template) => str.replace(template, (substr: string, b: string) => {
            let r = this.getValue(translatedParams, b);
            return isDefined(r) ? r : substr;
        }), expr);
    }

    getValue(target: any, key: string): string {
        let keys = key.trim().split('.');
        key = '';
        do {
            key += keys.shift();
            if (isDefined(target) && isDefined(target[key]) && (typeof target[key] === 'object' || !keys.length)) {
                target = target[key];
                key = '';
            } else if (!keys.length) {
                target = undefined;
            } else {
                key += '.';
            }
        } while (keys.length);

        return target;
    }

    translateParams(params) {
        return Object.keys(params).reduce((newParams, key) =>
                (params[key] && typeof params[key] === 'object') ?
                    {...newParams, [key]: this.translateParams(params[key])} :
                    {...newParams, [key]: this.translateClass.transform(params[key])}, {});
    }
}

function isDefined(value) {
    return typeof value !== 'undefined' && value !== null;
}
