#!/usr/bin/python3
import sys
import struct
import wrapper
import threading
import time
from wrapper import recv_from_any_link, send_to_link, get_switch_mac, get_interface_name


def create_vlan_tag(vlan_id):
    tpid = 0x8200
    vlan_tci = vlan_id & 0x0FFF  # Masking to ensure only last 12 bits
    vlan_tag = struct.pack('!HH', tpid, vlan_tci)
    return vlan_tag


def remove_vlan_tag(data):
    return data[:12] + data[16:]    


def parse_ethernet_header(data):
    dest_mac = data[0:6]
    src_mac = data[6:12]
    ether_type = (data[12] << 8) + data[13]
    vlan_id = -1

    if ether_type == 0x8200:
        vlan_tci = int.from_bytes(data[14:16], byteorder="big")
        vlan_id = vlan_tci & 0x0FFF
        ether_type = (data[16] << 8) + data[17]

    return dest_mac, src_mac, ether_type, vlan_id


def parse_config(switch_id):
    filename = f"configs/switch{switch_id}.cfg"
    port_vlan = {}
    trunk_ports = set()

    try:
        with open(filename, "r") as f:
            for line in f:
                stripped_line = line.strip()
                if not stripped_line:  # Skip empty lines
                    continue
                
                parts = stripped_line.split(' ')
                if len(parts) < 2:  # Ensure there are enough parts
                    continue
                
                if (len(parts) == 2):
                    port, vlan_type = parts[0], parts[1]
                    
                    if vlan_type.strip() == 'T':
                        trunk_ports.add(port)
                    else:
                        port_vlan[port] = int(vlan_type)

    except FileNotFoundError:
        print(f"File {filename} not found.")
    

    return port_vlan, trunk_ports



def send_vlan_packet(interface, data, length, port_vlan, trunk_ports, vlan_id, vlan_id_in):
    vlan_out_id = port_vlan.get(interface, -1)

    if interface in trunk_ports:
        if vlan_id == -1:
            data = data[:12] + create_vlan_tag(vlan_id_in) + data[12:]
            length = len(data)
            send_to_link(interface, data, length)
        else: send_to_link(interface, data, length)

    elif vlan_out_id == vlan_id_in:
        if vlan_id != -1:
            data = remove_vlan_tag(data)
            length = len(data)
            send_to_link(interface, data, length)
        else: send_to_link(interface, data, length)


def main():
    switch_id = sys.argv[1]
    num_interfaces = wrapper.init(sys.argv[2:])
    interfaces = range(num_interfaces)

    port_vlan, trunk_ports = parse_config(switch_id)
    MAC_table = {}

    print("# Starting switch with id {}".format(switch_id))
    print("[INFO] Switch MAC", ':'.join(f'{b:02x}' for b in get_switch_mac()))

    print(f"vLAna=s: {port_vlan}")
    print(f"vLAna=s: {trunk_ports}")

    while True:
        interface, data, length = recv_from_any_link()
        dest_mac, src_mac, ethertype, vlan_id = parse_ethernet_header(data)
        
        dest_mac_str = ':'.join(f'{b:02x}' for b in dest_mac)
        src_mac_str = ':'.join(f'{b:02x}' for b in src_mac)

        print(f"Destination MAC: {dest_mac_str}")
        print(f"Source MAC: {src_mac_str}")
        print(f"EtherType: {ethertype}")
        print(f"VLAN ID: {vlan_id}")

        MAC_table[src_mac_str] = interface
        vlan_id_in = vlan_id if vlan_id != -1 else port_vlan.get(interface, -1)

        if dest_mac_str in MAC_table:
            send_vlan_packet(MAC_table[dest_mac_str], data, length, port_vlan, trunk_ports, vlan_id, vlan_id_in)
        else:
            for i in interfaces:
                if i != interface:
                    send_vlan_packet(i, data, length, port_vlan, trunk_ports, vlan_id, vlan_id_in)


if __name__ == "__main__":
    main()
i receive this error Traceback (most recent call last):
  File "/home/traistaru-andreea/Desktop/RL/Tema_1/tema1-public/switch.py", line 324, in <module>
    main()
  File "/home/traistaru-andreea/Desktop/RL/Tema_1/tema1-public/switch.py", line 320, in main
    send_vlan_packet(i, data, length, port_vlan, trunk_ports, vlan_id, vlan_id_in)
  File "/home/traistaru-andreea/Desktop/RL/Tema_1/tema1-public/switch.py", line 283, in send_vlan_packet
    else: send_to_link(interface, data, length)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/traistaru-andreea/Desktop/RL/Tema_1/tema1-public/wrapper.py", line 60, in send_to_link
    assert(buffer_size < 1600)
           ^^^^^^^^^^^^^^^^^^
TypeError: '<' not supported between instances of 'bytes' and 'int' fix this