-- {{ protocol.name }}.lua
-- Generated by Oscura on {{ timestamp }}
--
-- Protocol: {{ protocol.description }}
-- Version: {{ protocol.version }}
{% if protocol.endian %}-- Endianness: {{ protocol.endian }}
{% endif %}

-- Protocol declaration
local {{ proto_var }} = Proto("{{ protocol.name }}", "{{ protocol.description }}")

-- Field declarations
{% for field in fields %}
local f_{{ field.name }} = {{ field.protofield_type }}(
    "{{ protocol.name }}.{{ field.name }}",
    "{{ field.display_name }}",
    {{ field.display_base }}
    {%- if field.value_string %}, {{ field.value_string }}{% endif %}
)
{% endfor %}

-- Register fields
{{ proto_var }}.fields = { {% for field in fields %}f_{{ field.name }}{% if not loop.last %}, {% endif %}{% endfor %} }

-- Dissector function
function {{ proto_var }}.dissector(buffer, pinfo, tree)
    local pktlen = buffer:len()

    -- Check minimum length
    if pktlen < {{ min_length }} then
        return 0  -- Not enough data
    end

    -- Set protocol column
    pinfo.cols.protocol = {{ proto_var }}.name

    -- Create protocol subtree
    local subtree = tree:add({{ proto_var }}, buffer(), "{{ protocol.description }}")
    local offset = 0

    -- Decode fields
{% for field in fields %}
    {% if field.condition %}
    -- Conditional field: {{ field.name }} ({{ field.condition }})
    -- TODO: Implement condition evaluation (user should add Lua condition logic)
    {% endif %}
    {% if field.is_variable_length %}
    -- Variable-length field: {{ field.name }}
    {% if field.size_field %}
    local {{ field.name }}_len = buffer({{ field.size_offset }}, {{ field.size_field_size }}):{{ field.size_reader }}()
    if offset + {{ field.name }}_len > pktlen then
        subtree:add_expert_info(PI_MALFORMED, PI_ERROR, "Truncated {{ field.name }}")
        return pktlen
    end
    subtree:add(f_{{ field.name }}, buffer(offset, {{ field.name }}_len))
    offset = offset + {{ field.name }}_len
    {% else %}
    -- Use remaining data for {{ field.name }}
    local {{ field.name }}_len = pktlen - offset
    subtree:add(f_{{ field.name }}, buffer(offset, {{ field.name }}_len))
    offset = offset + {{ field.name }}_len
    {% endif %}
    {% else %}
    -- Fixed-length field: {{ field.name }} ({{ field.size }} bytes)
    if offset + {{ field.size }} > pktlen then
        subtree:add_expert_info(PI_MALFORMED, PI_ERROR, "Truncated {{ field.name }}")
        return pktlen
    end
    subtree:add(f_{{ field.name }}, buffer(offset, {{ field.size }}))
    offset = offset + {{ field.size }}
    {% endif %}

{% endfor %}
    return offset
end

-- Protocol registration
{% if transport == "tcp" %}
-- Register on TCP port {{ port }}
local tcp_table = DissectorTable.get("tcp.port")
tcp_table:add({{ port }}, {{ proto_var }})
{% elif transport == "udp" %}
-- Register on UDP port {{ port }}
local udp_table = DissectorTable.get("udp.port")
udp_table:add({{ port }}, {{ proto_var }})
{% elif pattern %}
-- Register on pattern match
-- TODO: Implement heuristic dissector for pattern "{{ pattern }}" (user should add Lua heuristic code)
{% else %}
-- No automatic registration - manually register as needed
-- Example: DissectorTable.get("tcp.port"):add(PORT, {{ proto_var }})
{% endif %}
