<template name="cisco_ios_interface_config" results="per_template">
<doc>
*Authored by Codex GPT-5.*

Template to parse Cisco IOS interfaces configuration and normalize it to a
flat list of dictionaries suitable for Netbox import.

This template requires output of 'show running-config | section interface'.

The transform macro returns a list of dictionaries where each dictionary
contains the following keys (missing values are set to `null` / `None`):

- `name`: interface name string (e.g. GigabitEthernet0/1, Vlan100)
- `type`: ``other`` by default; ``bridge`` if "vlan" or "bvi" in name;
    ``lag`` if "port-channel" in name; ``virtual`` if "loopback", "tunnel",
    or if the interface name contains a dot (`.`)
- `enabled`: boolean; interfaces are `True` by default unless explicitly
    shutdown in the config
- `parent`: parent interface name or `null` (if the interface name contains
    a dot the parent is the part before the dot)
- `lag_id`: lag identifier integer (channel-group number) or `null`
- `lag_type`: ``lag`` for standard port channels or `null`
- `lacp_mode`: LACP mode string (e.g. ``active``, ``passive``) or `null`
- `lag`: Name of parent LAG interface e.g. `Port-channel10` or `null`
- `mtu`: integer MTU or `null`
- `mac_address`: string in MAC EUI format or `null`
- `speed`: integer speed in kbit/s or `null`
- `duplex`: string duplex setting or `null`
- `description`: string (empty string when not set)
- `mode`: ``tagged`` / ``access`` or `null`
- `untagged_vlan`: integer or `null`
- `tagged_vlans`: list of integers (empty list when none)
- `qinq_svlan`: integer inner VLAN from `second-dot1q` or `null`
- `vrf`: string or `null`
- `ipv4_addresses`: list of strings with IP/prefix (e.g. 10.0.0.1/24)
- `ipv6_addresses`: list of strings with IP/prefix (e.g. 2001:db8::1/64)

Example normalized output (YAML):

```yaml
- description: Users SVI
  duplex: null
  enabled: true
  ipv4_addresses:
  - 192.0.2.1/24
  ipv6_addresses: []
  lacp_mode: null
  lag: null
  lag_id: null
  lag_type: null
  mac_address: null
  mode: access
  mtu: 1500
  name: Vlan100
  parent: null
  qinq_svlan: null
  speed: null
  tagged_vlans: []
  type: bridge
  untagged_vlan: 100
  vrf: USERS
```

</doc>

<input>
commands = [
    "show running-config | section interface"
]
platform = [
    "cisco_ios", # Netmiko and Scrapli
    "ios", # NAPALM
]
</input>

<macro>
def transform_interfaces_to_records(data):
    from ttp_templates.utils.cisco_ios_process_show_running_config_pipe_section_interface import transform_interfaces_config

    return transform_interfaces_config(data)
</macro>

## ------------------------------------------------------------------------------------------
## Interfaces configuration
## ------------------------------------------------------------------------------------------
<group functions="contains('name')">
interface {{ name | _start_ }}
 description {{ description | re(".*") | default("") }}
 shutdown {{ enabled | set(False) | default(True) }}
 no shutdown {{ enabled | set(True) | default(True) }}
 mtu {{ mtu | to_int }}
 ip vrf forwarding {{ vrf }}
 vrf forwarding {{ vrf }}
 encapsulation dot1Q {{ dot1q | to_int | let("mode", "tagged") }} second-dot1q {{ qinq_svlan | to_int }}
 encapsulation dot1Q {{ dot1q | to_int | let("mode", "tagged") }}
 switchport mode trunk {{ mode | set("tagged") }}
 switchport mode access {{ mode | set("access") }}
 switchport access vlan {{ untagged_vlan | to_int | let("mode", "access") }}
 switchport trunk native vlan {{ untagged_vlan | to_int }}
 switchport trunk allowed vlan {{ tagged_vlans | unrange(rangechar='-', joinchar=',') | split(",") | joinmatches }}
 switchport trunk allowed vlan add {{ tagged_vlans | unrange(rangechar='-', joinchar=',') | split(",") | joinmatches }}
 channel-group {{ lag_id | to_int | let("lag_type", "lag") }} mode {{ lacp_mode }}
 mac-address {{ mac_address | mac_eui }}
 speed {{ speed }}
 duplex {{ duplex }}

 <group name="ipv4_addresses*" method="table">
 ip address {{ ip | IP }} {{ mask }}
 ip address {{ ip | IP }} {{ mask }} secondary
 </group>

 <group name="ipv6_addresses*" method="table">
 ipv6 address {{ ip | IPV6 }}/{{ mask }}
 </group>

!{{ _end_ }}
</group>

<output macro="transform_interfaces_to_records"/>

</template>
