#!/usr/bin/env python3
#
# Copyright (C) 2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import jinja2

from argparse import ArgumentParser
from vyos.ifconfig import Section
from vyos.ifconfig import BondIf
from vyos.utils.file import read_file

from sys import exit

parser = ArgumentParser()
parser.add_argument("--slaves", action="store_true", help="Show LLDP neighbors on all interfaces")
parser.add_argument("--interface", action="store", help="Show LLDP neighbors on specific interface")

args = parser.parse_args()

all_bonds = Section.interfaces('bonding')
# we are not interested in any bond vlan interface
all_bonds = [x for x in all_bonds if '.' not in x]

TMPL_BRIEF = """Interface    Mode                   State    Link   Slaves
{% for interface in data %}
{{ "%-12s" | format(interface.ifname) }} {{ "%-22s" | format(interface.mode) }} {{ "%-8s" | format(interface.admin_state) }} {{ "%-6s" | format(interface.oper_state) }} {{ interface.members | join(' ') }}
{% endfor %}
"""

TMPL_INDIVIDUAL_BOND = """Interface        RX: bytes  packets     TX: bytes  packets
{{ "%-16s" | format(data.ifname) }} {{ "%-10s" | format(data.rx_bytes) }} {{ "%-11s" | format(data.rx_packets) }} {{ "%-10s" | format(data.tx_bytes) }} {{ data.tx_packets }}
{% for member in data.members if data.members is defined %}
    {{ "%-12s" | format(member.ifname) }} {{ "%-10s" | format(member.rx_bytes) }} {{ "%-11s" | format(member.rx_packets) }} {{ "%-10s" | format(member.tx_bytes) }} {{ member.tx_packets }}
{% endfor %}
"""

if args.slaves and args.interface:
    exit('Can not use both --slaves and --interfaces option at the same time')
    parser.print_help()

elif args.slaves:
    data = []
    template = TMPL_BRIEF
    for bond in all_bonds:
        tmp = BondIf(bond)
        cfg_dict = {}
        cfg_dict['ifname'] = bond
        cfg_dict['mode'] = tmp.get_mode()
        cfg_dict['admin_state'] = tmp.get_admin_state()
        cfg_dict['oper_state'] = tmp.operational.get_state()
        cfg_dict['members'] = tmp.get_slaves()
        data.append(cfg_dict)

elif args.interface:
    template = TMPL_INDIVIDUAL_BOND
    data = {}
    data['ifname'] = args.interface
    data['rx_bytes'] = read_file(f'/sys/class/net/{args.interface}/statistics/rx_bytes')
    data['rx_packets'] = read_file(f'/sys/class/net/{args.interface}/statistics/rx_packets')
    data['tx_bytes'] = read_file(f'/sys/class/net/{args.interface}/statistics/tx_bytes')
    data['tx_packets'] = read_file(f'/sys/class/net/{args.interface}/statistics/tx_packets')

    # each bond member interface has its own statistics
    data['members'] = []
    for member in BondIf(args.interface).get_slaves():
        tmp = {}
        tmp['ifname'] = member
        tmp['rx_bytes'] = read_file(f'/sys/class/net/{member}/statistics/rx_bytes')
        tmp['rx_packets'] = read_file(f'/sys/class/net/{member}/statistics/rx_packets')
        tmp['tx_bytes'] = read_file(f'/sys/class/net/{member}/statistics/tx_bytes')
        tmp['tx_packets'] = read_file(f'/sys/class/net/{member}/statistics/tx_packets')
        data['members'].append(tmp)

else:
    parser.print_help()
    exit(1)

tmpl = jinja2.Template(template, trim_blocks=True)
config_text = tmpl.render(data=data)
print(config_text)