/**
 * @file {{filename}}_lmsg.ts
 *
 * @brief {{filename}}_lmsg Classes
 * 
 * This file contains the declaration of the message classes generated by the Lions Compiler.
 * 
 * @details
 * This file was generated by the Lions Compiler (https://github.com/ItsNotSoftware/lions) on {{date}}.
 * Modifying this file manually is not recommended as it may lead to unexpected behavior.
 * 
 * @note
 * Generated files should not be manually edited.
 * 
 * @author Lions Compiler
*/

import { LMsg, Header } from './lions.ts';

const msg_id = {
{% for msg in msgs %}    {{msg.name}}: {{msg.id}}{% if not loop.last %},{% endif %}
{% endfor %}};

const msg_period = {
{% for msg in msgs %}    {{msg.name}}: {{msg.period}}{% if not loop.last %},{% endif %}
{% endfor %}};

{% for msg in msgs %}
class {{msg.name | capitalize}}Msg {
    header: Header;
{% for field in msg.fields %}    {{field.name}}: {{field.type}};
{% endfor %}
    constructor({% for field in msg.fields %}{{field.name}}: {{field.type}}{% if not loop.last %}, {% endif %}{% endfor %}) {
        this.header = new Header();
{% for field in msg.fields %}        this.{{field.name}} = {{field.name}};
{% endfor %}    }

    static fromLMsg(msg: LMsg): {{msg.name | capitalize}}Msg {
        const dataView = new DataView(msg.payload);{% for field in msg.fields %}
        {% if field.buff_type == 'string' %}const {{field.name}} = new TextDecoder().decode(msg.payload.slice({{field.start}}, {{field.start}} + {{field.size}})).replace(/\0.*$/,"");
        {% elif field.buff_type == 'Int8' or field.buff_type == 'Uint8'  %}const {{field.name}} = dataView.get{{field.buff_type | capitalize}}({{field.start}});
        {% else %}const {{field.name}} = dataView.get{{field.buff_type | capitalize}}({{field.start}}, true);  // true for little-endian{% endif %}{% endfor %}

        let instance = new {{msg.name | capitalize}}Msg({% for field in msg.fields %}{{field.name}}{% if not loop.last %}, {% endif %}{% endfor %});
        instance.header = msg.header;

        return instance;
    }

    encode(src: number, dst: number, next_hop: number): LMsg {
        const msg = new LMsg({{msg.payload_size}});
        
        msg.header.src = src;
        msg.header.dst = dst;
        msg.header.next_hop = next_hop;
        msg.header.msg_id = msg_id.{{msg.name}};
        
        const dataView = new DataView(msg.payload);{% for field in msg.fields %}
        {% if field.buff_type == 'string' %}
        const encoded{{field.name | capitalize}} = new TextEncoder().encode(this.{{field.name}});
        for (let i = 0; i < Math.min(encoded{{field.name | capitalize}}.length, {{field.size}}); i++) {
            dataView.setUint8({{field.start}} + i, encoded{{field.name | capitalize}}[i]);
        }
        
        if (encoded{{field.name | capitalize}}.length < {{field.size}}) {
            dataView.setUint8({{field.start}} + encoded{{field.name | capitalize}}.length, 0);
        }
        {%  elif field.buff_type == 'Int8' or field.buff_type == 'Uint8' %}dataView.set{{field.buff_type | capitalize}}({{field.start}}, this.{{field.name}});
        {% else %}dataView.set{{field.buff_type | capitalize}}({{field.start}}, this.{{field.name}}, true);  // true for little-endian{% endif %}{% endfor %}

        msg.calculateChecksum();

        return msg;
    }
}
{% endfor %}

export { msg_id, msg_period, {% for msg in msgs %}{{msg.name | capitalize}}Msg{% if not loop.last %}, {% endif %}{% endfor %} };
