"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Language_1 = require("./Language");
class GenericModelSerializer {
    constructor() {
        this.language = Language_1.Language.getInstance();
    }
    toTypeScriptInstance(jsonObject) {
        const result = this.toTypeScriptInstanceInternal(jsonObject);
        return result;
    }
    toTypeScriptInstanceInternal(jsonObject) {
        if (jsonObject === null) {
            throw new Error("jsonObject is null, cannot convert to TypeScript");
        }
        const type = jsonObject["$typename"];
        if (!(!!type)) {
            return null;
        }
        const result = this.language.createConcept(type);
        for (let property of this.language.allConceptProperties(type)) {
            const value = jsonObject[property.name];
            if (value === undefined) {
                continue;
            }
            switch (property.propertyType) {
                case "primitive":
                    if (property.isList) {
                        result[property.name] = [];
                        for (var item in value) {
                            result[property.name].push(value[item]);
                        }
                    }
                    else {
                        if (typeof value === "string") {
                            result[property.name] = value;
                        }
                        else if (typeof value === "number") {
                            result[property.name] = value;
                        }
                        else if (typeof value === "boolean") {
                            result[property.name] = value;
                        }
                    }
                    break;
                case "part":
                    if (property.isList) {
                        for (var item in value) {
                            result[property.name].push(this.toTypeScriptInstance(value[item]));
                        }
                    }
                    else {
                        if (!!value) {
                            result[property.name] = this.toTypeScriptInstance(value);
                        }
                    }
                    break;
                case "reference":
                    if (property.isList) {
                        for (var item in value) {
                            result[property.name].push(this.language.referenceCreator(value[item], property.type));
                        }
                    }
                    else {
                        result[property.name] = this.language.referenceCreator(value, property.type);
                    }
                    break;
                default:
            }
        }
        return result;
    }
    convertToJSON(tsObject, publicOnly) {
        const typename = tsObject.piLanguageConcept();
        var result;
        if (publicOnly !== undefined && publicOnly) {
            if (this.language.concept(typename).isPublic || this.language.concept(typename).isUnit) {
                result = this.convertToJSONinternal(tsObject, true, typename);
            }
        }
        else {
            result = this.convertToJSONinternal(tsObject, false, typename);
        }
        return result;
    }
    convertToJSONinternal(tsObject, publicOnly, typename) {
        var result = { $typename: typename };
        for (let p of this.language.allConceptProperties(typename)) {
            if (publicOnly) {
                if (p.isPublic) {
                    this.convertPropertyToJSON(p, tsObject, publicOnly, result);
                }
            }
            else {
                this.convertPropertyToJSON(p, tsObject, publicOnly, result);
            }
        }
        return result;
    }
    convertPropertyToJSON(p, tsObject, publicOnly, result) {
        switch (p.propertyType) {
            case "part":
                var value = tsObject[p.name];
                if (p.isList) {
                    const parts = tsObject[p.name];
                    result[p.name] = [];
                    for (var i = 0; i < parts.length; i++) {
                        result[p.name][i] = this.convertToJSON(parts[i], publicOnly);
                    }
                }
                else {
                    result[p.name] = !!value ? this.convertToJSON(value, publicOnly) : null;
                }
                break;
            case "reference":
                if (p.isList) {
                    const references = tsObject[p.name];
                    result[p.name] = [];
                    for (var i = 0; i < references.length; i++) {
                        result[p.name][i] = references[i]["name"];
                    }
                }
                else {
                    const value = tsObject[p.name];
                    result[p.name] = !!value ? tsObject[p.name]["name"] : null;
                }
                break;
            case "primitive":
                var value = tsObject[p.name];
                if (typeof value === "string") {
                    result[p.name] = value;
                }
                else if (typeof value === "number") {
                    result[p.name] = value;
                }
                else if (typeof value === "boolean") {
                    result[p.name] = value;
                }
                break;
            default:
                break;
        }
    }
}
exports.GenericModelSerializer = GenericModelSerializer;
//# sourceMappingURL=GenericModelSerializer.js.map