class SwitchCore(object):
    def __init__(self, switch_configuration):
    def launch(self, protocol, terminal_controller):
    def get_default_ports():
    def get_netconf_protocol(self):
    def get_http_resource(self): class ConfigCommandProcessor(BaseCommandProcessor):
    def __init__(self, config_vlan, config_vrf, config_interface, config_virtual_interface):
        super(ConfigCommandProcessor, self).__init__()
        self.config_vlan_processor = config_vlan
        self.config_vrf_processor = config_vrf
        self.config_interface_processor = config_interface
        self.config_virtual_interface_processor = config_virtual_interface

    def get_prompt(self):
        return "SSH@%s(config)#" % self.switch_configuration.name

    def do_vlan(self, raw_number, *args):
        number = int(raw_number)
        if number < 0:
            self.write_line("Invalid input -> -1")
            self.write_line("Type ? for a list")
        elif number == 0:
            self.write_line("Error: vlan ID value 0 not allowed.")
        elif number > 4090:
            self.write_line("Error: vlan id %s is outside of allowed max of 4090" % raw_number)
        else:
            vlan = self.switch_configuration.get_vlan(number)
            if not vlan:
                vlan = self.switch_configuration.new("Vlan", number)
                self.switch_configuration.add_vlan(vlan)
            if len(args) > 0:
                if "name".startswith(args[0]):
                    vlan.name = args[1]
            self.move_to(self.config_vlan_processor, vlan)

    def do_no_vlan(self, *args):
        vlan = self.switch_configuration.get_vlan(int(args[0]))
        if vlan:
            self.switch_configuration.remove_vlan(vlan)
            bound_ve = next(
                (p for p in self.switch_configuration.ports if isinstance(p, VlanPort) and p.vlan_id == vlan.number),
                None)
            if bound_ve:
                self.switch_configuration.remove_port(bound_ve)

            for port in self.switch_configuration.ports:
                if port.trunk_vlans is None:
                    if port.access_vlan == vlan.number:
                        port.access_vlan = None
                else:
                    if port.trunk_native_vlan == vlan.number:
                        port.trunk_native_vlan = None
                    if vlan.number in port.trunk_vlans:
                        port.trunk_vlans.remove(vlan.number)
                        if len(port.trunk_vlans) == 0:
                            port.trunk_vlans = None

    def do_interface(self, *args):
        port = self.switch_configuration.get_port_by_partial_name("".join(args))
        if port:
            if isinstance(port, VlanPort):
                self.move_to(self.config_virtual_interface_processor, port)
            else:
                self.move_to(self.config_interface_processor, port)
        else:
            if "ve".startswith(args[0]):
                self.write_line("Error - invalid virtual ethernet interface number.")
            else:
                [self.write_line(l) for l in explain_missing_port(" ".join(args))]

    def do_no_interface(self, *args):
        port = self.switch_configuration.get_port_by_partial_name("".join(args))
        if port:
            if isinstance(port, VlanPort):
                self.switch_configuration.remove_port(port)
                self.switch_configuration.add_port(self.switch_configuration.new("VlanPort", port.vlan_id, port.name))
            elif isinstance(port, Port):
                trunk_vlans = port.trunk_vlans
                access_vlan = port.access_vlan
                trunk_native_vlan = port.trunk_native_vlan
                port.reset()
                port.trunk_vlans = trunk_vlans
                port.access_vlan = access_vlan
                port.trunk_native_vlan = trunk_native_vlan
        else:
            [self.write_line(l) for l in explain_missing_port(" ".join(args))]

    def do_no_ip(self, cmd, *args):
        if "vrf".startswith(cmd):
            self.switch_configuration.remove_vrf(args[0])
        elif "route".startswith(cmd):
            self.switch_configuration.remove_static_route(args[0], args[1])

    def do_ip(self, cmd, *args):
        if "vrf".startswith(cmd):
            vrf = self.switch_configuration.new("VRF", args[0])
            self.switch_configuration.add_vrf(vrf)
            self.move_to(self.config_vrf_processor, vrf)
        elif "route".startswith(cmd):
            static_route = self.switch_configuration.new("Route", *args)
            self.switch_configuration.add_static_route(static_route)

    def do_exit(self):
        self.is_done = True class ConfigInterfaceCommandProcessor(BaseCommandProcessor):
    def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args):
        super(ConfigInterfaceCommandProcessor, self).init(switch_configuration, terminal_controller, logger, piping_processor)
        self.port = args[0]

    def get_prompt(self):
        return "SSH@%s(config-if-e1000-%s)#" % (self.switch_configuration.name, split_port_name(self.port.name)[1])

    def do_enable(self, *_):
        self.port.shutdown = False

    def do_disable(self, *_):
        self.port.shutdown = None

    def do_vrf(self, *args):
        if "forwarding".startswith(args[0]):
            if len(args) > 1:
                if isinstance(self.port, VlanPort):
                    for ip in self.port.ips[:]:
                        self.port.remove_ip(ip)
                vrf = self.switch_configuration.get_vrf(args[1])
                if vrf is None:
                    self.write_line("Error - VRF({}) does not exist or Route-Distinguisher not specified or Address Family not configured".format(
                        args[1]))
                else:
                    self.port.vrf = vrf
                    self.write_line("Warning: All IPv4 and IPv6 addresses (including link-local) on this interface have been removed")

    def do_no_vrf(self, *args):
        if "forwarding".startswith(args[0]):
            if len(args) == 1:
                self.write_line("Incomplete command.")
            elif self.port.vrf.name != args[1]:
                self.write_line("Error - VRF({}) does not exist or Route-Distinguisher not specified or Address Family not configured".format(
                    args[1]))
            else:
                if isinstance(self.port, VlanPort):
                    for ip in self.port.ips[:]:
                        self.port.remove_ip(ip)
                self.port.vrf = None
                self.write_line("Warning: All IPv4 and IPv6 addresses (including link-local) on this interface have been removed")

    def do_exit(self):
        self.is_done = True

    def do_port_name(self, *args):
        self.port.description = " ".join(args)

    def do_no_port_name(self, *_):
        self.port.description = None class ConfigVirtualInterfaceCommandProcessor(ConfigInterfaceCommandProcessor):
    def __init__(self, config_virtual_interface_vrrp):
        super(ConfigVirtualInterfaceCommandProcessor, self).__init__()
        self.config_virtual_interface_vrrp = config_virtual_interface_vrrp

    def get_prompt(self):
        return "SSH@%s(config-vif-%s)#" % (self.switch_configuration.name, self.port.vlan_id)

    def do_ip(self, *args):
        if "address".startswith(args[0]):
            new_ip = IPNetwork(args[1])
            ip_owner, existing_ip = self.switch_configuration.get_port_and_ip_by_ip(new_ip.ip)
            if not ip_owner:
                self.port.add_ip(new_ip)
            else:
                if ip_owner == self.port:
                    for ip in self.port.ips:
                        if new_ip.ip == ip.ip:
                            self.write_line("IP/Port: Errno(6) Duplicate ip address")
                            break
                        else:
                            if new_ip.ip in ip:
                                if len(args) > 2 and "secondary".startswith(args[2]):
                                    if not next((ip for ip in self.port.secondary_ips if ip.ip == new_ip.ip), False):
                                        self.port.add_secondary_ip(new_ip)
                                    else:
                                        self.write_line("IP/Port: Errno(6) Duplicate ip address")
                                        break
                                else:
                                    self.write_line(
                                        "IP/Port: Errno(15) Can only assign one primary ip address per subnet")
                                    break
                else:
                    self.write_line("IP/Port: Errno(11) ip subnet overlap with another interface")

        if "access-group".startswith(args[0]):
            if "in".startswith(args[2]):
                self.port.access_group_in = args[1]
            elif "out".startswith(args[2]):
                self.port.access_group_out = args[1]
            self.write_line("Warning: An undefined or zero length ACL has been applied. "
                            "Filtering will not occur for the specified interface VE {} (outbound)."
                            .format(self.port.vlan_id))

        if "vrrp-extended".startswith(args[0]):
            if "vrid".startswith(args[1]):
                group = args[2]
                vrrp = self.port.get_vrrp_group(group)
                if vrrp is None:
                    vrrp = self.switch_configuration.new("VRRP", group)
                    self.port.vrrps.append(vrrp)
                self.move_to(self.config_virtual_interface_vrrp, self.port, vrrp)

            if "auth-type".startswith(args[1]):
                if "simple-text-auth".startswith(args[2]):
                    self.port.vrrp_common_authentication = args[3]
                elif "no-auth".startswith(args[2]):
                    self.port.vrrp_common_authentication = None

        if "helper-address".startswith(args[0]):
            if len(args) == 1:
                self.write_line("Incomplete command.")
            elif len(args) > 2:
                self.write_line("Invalid input -> {}".format(" ".join(args[2:])))
                self.write_line("Type ? for a list")
            else:
                ip_address = IPAddress(args[1])
                if ip_address not in self.port.ip_helpers:
                    self.port.ip_helpers.append(ip_address)
                else:
                    self.write_line("UDP: Errno(7) Duplicate helper address")

        if "redirect".startswith(args[0]):
            self.port.ip_redirect = True

    def do_no_ip(self, *args):
        if "address".startswith(args[0]):
            deleting_ip = IPNetwork(args[1])
            if next((ip for ip in self.port.secondary_ips if ip.ip == deleting_ip.ip), False):
                self.port.remove_secondary_ip(deleting_ip)
            else:
                if not next((ip for ip in self.port.secondary_ips if ip in deleting_ip), False):
                    self.port.remove_ip(deleting_ip)
                else:
                    self.write_line("IP/Port: Errno(18) Delete secondary address before deleting primary address")
        if "access-group".startswith(args[0]):
            if len(args) < 3:
                self.write_line("Error: Wrong Access List Name %s" % args[1])
            else:
                if "in".startswith(args[2]):
                    if self.port.access_group_in == args[1]:
                        self.port.access_group_in = None
                    else:
                        self.write_line("Error: Wrong Access List Name %s" % args[1])
                elif "out".startswith(args[2]):
                    if self.port.access_group_out == args[1]:
                        self.port.access_group_out = None
                    else:
                        self.write_line("Error: Wrong Access List Name %s" % args[1])

        if "vrrp-extended".startswith(args[0]):
            if "vrid".startswith(args[1]):
                group = args[2]
                vrrp = self.port.get_vrrp_group(group)
                if vrrp:
                    self.port.vrrps.remove(vrrp)

            if "auth-type".startswith(args[1]):
                if "simple-text-auth".startswith(args[2]) and len(args) == 4:
                    self.do_ip(*"vrrp-extended auth-type no-auth".split())
                else:
                    self.write_line("Incomplete command.")

        if "helper-address".startswith(args[0]):
            if len(args) == 1:
                self.write_line("Incomplete command.")
            elif len(args) > 2:
                self.write_line("Invalid input -> {}".format(" ".join(args[2:])))
                self.write_line("Type ? for a list")
            else:
                ip_address = IPAddress(args[1])
                if ip_address in self.port.ip_helpers:
                    self.port.ip_helpers.remove(ip_address)
                else:
                    self.write_line("UDP: Errno(10) Helper address not configured")

        if "redirect".startswith(args[0]):
            self.port.ip_redirect = False class ConfigVirtualInterfaceVrrpCommandProcessor(BaseCommandProcessor):
    def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args):
        super(ConfigVirtualInterfaceVrrpCommandProcessor, self).init(switch_configuration, terminal_controller, logger, piping_processor)
        self.port, self.vrrp = args

    def get_prompt(self):
        return "SSH@%s(config-vif-%s-vrid-%s)#" % (
            self.switch_configuration.name, self.port.vlan_id, self.vrrp.group_id)

    def do_backup(self, *args):
        if "priority".startswith(args[0]) and "track-priority".startswith(args[2]):
            self.vrrp.priority = args[1]
            if len(self.vrrp.track) > 0:
                track_port = list(self.vrrp.track.keys())[0]
            else:
                track_port = None
            self.vrrp.track.update({track_port: args[3]})

    def do_no_backup(self, *_):
        self.vrrp.priority = None
        if len(self.vrrp.track) > 0:
            track_port = list(self.vrrp.track.keys())[0]
        else:
            track_port = None
        self.vrrp.track.update({track_port: None})

    def do_ip_address(self, *args):
        if self.vrrp.ip_addresses is not None:
            self.vrrp.ip_addresses.append(args[0])
        else:
            self.vrrp.ip_addresses = [args[0]]

    def do_no_ip_address(self, *args):
        if args[0] in self.vrrp.ip_addresses:
            self.vrrp.ip_addresses.remove(args[0])

    def do_hello_interval(self, *args):
        self.vrrp.timers_hello = args[0]

    def do_no_hello_interval(self, *_):
        self.vrrp.timers_hello = None

    def do_dead_interval(self, *args):
        self.vrrp.timers_hold = args[0]

    def do_no_dead_interval(self, *_):
        self.vrrp.timers_hold = None

    def do_advertise(self, *_):
        self.vrrp.advertising = True

    def do_no_advertise(self, *_):
        self.vrrp.advertising = False

    def do_track_port(self, *args):
        old_value = None

        if len(self.vrrp.track) > 0:
            old_value = list(self.vrrp.track.values())[0]

        self.vrrp.track = {' '.join(args[0:2]): old_value}

    def do_no_track_port(self, *_):
        old_value = None

        if len(self.vrrp.track) > 0:
            old_value = list(self.vrrp.track.values())[0]

        self.vrrp.track = {None: old_value}

    def do_activate(self, *_):
        self.vrrp.activated = True
        self.is_done = True

    def do_no_activate(self, *_):
        self.vrrp.activated = False

    def do_exit(self):
        self.is_done = True class ConfigVlanCommandProcessor(BaseCommandProcessor):
    def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args):
        super(ConfigVlanCommandProcessor, self).init(switch_configuration, terminal_controller, logger, piping_processor)
        self.vlan = args[0]

    def get_prompt(self):
        return "SSH@%s(config-vlan-%s)#" % (self.switch_configuration.name, self.vlan.number)

    def do_untagged(self, *args):
        port = self.switch_configuration.get_port_by_partial_name(" ".join(args))
        if port is not None:
            if port.trunk_vlans is None:
                port.access_vlan = self.vlan.number
            else:
                port.trunk_native_vlan = self.vlan.number
        else:
            self.write_line("Invalid input -> %s" % " ".join(args[1:]))
            self.write_line("Type ? for a list")

    def do_no_untagged(self, *args):
        port = self.switch_configuration.get_port_by_partial_name(" ".join(args))

        if port is not None:
            if port.access_vlan != self.vlan.number and port.trunk_native_vlan != self.vlan.number:
                self.write_line("Error: ports ethe {} are not untagged members of vlan {}".format(args[1], self.vlan.number))
                return

            if port.trunk_vlans is None:
                port.access_vlan = None
            else:
                port.trunk_native_vlan = None
        else:
            self.write_line("Invalid input -> %s" % " ".join(args[1:]))
            self.write_line("Type ? for a list")

    def do_tagged(self, *args):
        port = self.switch_configuration.get_port_by_partial_name(" ".join(args))
        if port is not None:
            if port.trunk_vlans is None:
                port.trunk_vlans = []
                port.trunk_native_vlan = port.access_vlan or 1
                port.access_vlan = None
            if self.vlan.number not in port.trunk_vlans:
                port.trunk_vlans.append(self.vlan.number)
        else:
            self.write_line("Invalid input -> %s" % " ".join(args[1:]))
            self.write_line("Type ? for a list")

    def do_no_tagged(self, *args):
        port = self.switch_configuration.get_port_by_partial_name(" ".join(args))
        if port is not None:
            if port.trunk_vlans is None or self.vlan.number not in port.trunk_vlans:
                self.write_line("Error: ports ethe {} are not tagged members of vlan {}".format(args[1], self.vlan.number))
                return

            port.trunk_vlans.remove(self.vlan.number)
            if len(port.trunk_vlans) == 0:
                port.trunk_vlans = None
                if port.trunk_native_vlan and port.trunk_native_vlan != 1:
                    port.access_vlan = port.trunk_native_vlan
                port.trunk_native_vlan = None
        else:
            self.write_line("Invalid input -> %s" % " ".join(args[1:]))
            self.write_line("Type ? for a list")

    def do_router_interface(self, *args):
        if len(args) != 2 or args[0] != "ve":
            self.write_line("Invalid input -> {}".format(" ".join(args)))
            self.write_line("Type ? for a list")
        else:
            actual_ve = next(
                (p for p in self.switch_configuration.ports if isinstance(p, VlanPort) and p.vlan_id == self.vlan.number),
                False)
            if not actual_ve:
                name = "ve {}".format(args[1])
                self.switch_configuration.add_port(self.switch_configuration.new("VlanPort", self.vlan.number,
                                                                                 name))
            else:
                self.write_line("Error: VLAN: %s  already has router-interface %s" % (
                    self.vlan.number, split_port_name(actual_ve.name)[1]))

    def do_no_router_interface(self, *_):
        self.switch_configuration.remove_port(next(
            p for p in self.switch_configuration.ports if isinstance(p, VlanPort) and p.vlan_id == self.vlan.number))

    def do_exit(self):
        self.is_done = True class ConfigVrfCommandProcessor(BaseCommandProcessor):
    def init(self, switch_configuration, terminal_controller, logger, piping_processor, *args):
        super(ConfigVrfCommandProcessor, self).init(switch_configuration, terminal_controller, logger, piping_processor)
        self.vrf = args[0]

    def get_prompt(self):
        return "SSH@%s(config-vrf-%s)#" % (self.switch_configuration.name, self.vrf.name)

    def do_exit(self):
        self.is_done = True class DefaultCommandProcessor(BaseCommandProcessor):
    def __init__(self, enabled):
        super(DefaultCommandProcessor, self).__init__()
        self.enabled_processor = enabled

    def get_prompt(self):
        return "SSH@%s>" % self.switch_configuration.name

    def delegate_to_sub_processor(self, line):
        processed = self.sub_processor.process_command(line)
        if self.sub_processor.is_done:
            self.is_done = True
        return processed

    def do_enable(self):
        self.write("Password:")
        self.replace_input = ''
        self.continue_to(self.continue_enabling)

    def continue_enabling(self, line):
        self.replace_input = False
        if line == "" or line in self.switch_configuration.privileged_passwords:
            self.move_to(self.enabled_processor)
        else:
            self.write_line("Error - Incorrect username or password.") class EnabledCommandProcessor(BaseCommandProcessor):
    def __init__(self, config):
        super(EnabledCommandProcessor, self).__init__()
        self.config_processor = config

    def get_prompt(self):
        return "SSH@%s#" % self.switch_configuration.name

    def do_configure(self, *_):
        self.move_to(self.config_processor)

    def do_show(self, *args):
        if "running-config".startswith(args[0]):
            if "vlan".startswith(args[1]):
                self.show_run_vlan()
            if "interface".startswith(args[1]):
                self.show_run_int(args)
        elif "interfaces".startswith(args[0]):
            self.show_int(args)
        elif "vlan".startswith(args[0]):
            if args[1].isdigit():
                self._show_vlan(int(args[1]))
            elif "brief".startswith(args[1]):
                self.show_vlan_brief()
            elif "ethernet".startswith(args[1]):
                self.show_vlan_int(args)
            else:
                self.write_line("Invalid input -> %s" % args[1])
                self.write_line("Type ? for a list")
        elif "ip".startswith(args[0]) and "route".startswith(args[1]) and "static".startswith(args[2]):
            routes = self.switch_configuration.static_routes
            if routes:
                self.write_line("        Destination        Gateway        Port          Cost          Type Uptime src-vrf")
            for n, route in enumerate(routes):
                self.write_line("{index:<8}{destination:<18} {next_hop:}".format(index=n+1, destination=str(route.dest), next_hop=str(route.next_hop)))
            self.write_line("")
        elif "version".startswith(args[0]):
            self.show_version()

    def do_ncopy(self, protocol, url, filename, target):
        try:
            SwitchTftpParser(self.switch_configuration).parse(url, filename, self.config_processor)
            self.write_line("done")
        except Exception as e:
            self.logger.warning("tftp parsing went wrong : %s" % str(e))
            self.write_line("%s: Download to %s failed - Session timed out" % (protocol.upper(), target))

    def do_skip_page_display(self, *args):
        pass

    def do_write(self, *args):
        self.switch_configuration.commit()

    def do_exit(self):
        self.is_done = True

    def show_run_vlan(self):
        self.write_line("spanning-tree")
        self.write_line("!")
        self.write_line("!")
        for vlan in sorted(self.switch_configuration.vlans, key=lambda v: v.number):
            if vlan_name(vlan):
                self.write_line("vlan %d name %s" % (vlan.number, vlan_name(vlan)))
            else:
                self.write_line("vlan %d" % vlan.number)

            untagged_ports = []
            for port in self.switch_configuration.ports:
                if not isinstance(port, VlanPort):
                    if vlan.number == 1 and port.access_vlan is None and port.trunk_native_vlan is None:
                        untagged_ports.append(port)
                    elif port.access_vlan == vlan.number or port.trunk_native_vlan == vlan.number:
                        untagged_ports.append(port)

            if len(untagged_ports) > 0:
                if vlan.number == 1:
                    self.write_line(" no untagged %s" % to_port_ranges(untagged_ports))
                else:
                    self.write_line(" untagged %s" % to_port_ranges(untagged_ports))

            tagged_ports = [p for p in self.switch_configuration.ports if
                            p.trunk_vlans and vlan.number in p.trunk_vlans]
            if tagged_ports:
                self.write_line(" tagged %s" % to_port_ranges(tagged_ports))

            vif = self.get_interface_vlan_for(vlan)
            if vif is not None:
                self.write_line(" router-interface %s" % vif.name)

            self.write_line("!")
        self.write_line("!")
        self.write_line("")

    def show_run_int(self, args):
        port_list = []
        if len(args) < 3:
            port_list = sorted(self.switch_configuration.ports, key=lambda e: ("a" if not isinstance(e, VlanPort) else "b") + e.name)
        else:
            if "ve".startswith(args[2]):
                port = self.switch_configuration.get_port_by_partial_name(" ".join(args[2:]))
                if not port:
                    self.write_line("Error - %s was not configured" % " ".join(args[2:]))
                else:
                    port_list = [port]
            else:
                port_type, port_number = split_port_name("".join(args[2:]))
                port = self.switch_configuration.get_port_by_partial_name(port_number)
                if not port:
                    self.write_line("")
                else:
                    port_list = [port]
        if len(port_list) > 0:
            for port in port_list:
                attributes = get_port_attributes(port)
                if len(attributes) > 0 or isinstance(port, VlanPort):
                    self.write_line("interface %s" % port.name)
                    for a in attributes:
                        self.write_line(" " + a)
                    self.write_line("!")

            self.write_line("")

    def show_int(self, args):
        ports = []
        port_name = " ".join(args[1:])
        if len(args) > 1:
            port = self.switch_configuration.get_port_by_partial_name(port_name)
            if port:
                ports.append(port)
        else:
            ports = self.switch_configuration.ports
        if not ports:
            [self.write_line(l) for l in explain_missing_port(port_name)]
        for port in ports:
            if isinstance(port, VlanPort):
                _, port_id = split_port_name(port.name)
                self.write_line("Ve%s is down, line protocol is down" % port_id)
                self.write_line("  Hardware is Virtual Ethernet, address is 0000.0000.0000 (bia 0000.0000.0000)")
                if port.description:
                    self.write_line("  Port name is %s" % port.description)
                else:
                    self.write_line("  No port name")

                self.write_line("  Vlan id: %s" % port.vlan_id)
                self.write_line("  Internet address is %s, IP MTU 1500 bytes, encapsulation ethernet" % (
                    port.ips[0] if port.ips else "0.0.0.0/0"))
            else:
                _, port_id = split_port_name(port.name)
                self.write_line("GigabitEthernet%s is %s, line protocol is down" % (
                    port_id, "down" if port.shutdown is False else "disabled"))
                self.write_line("  Hardware is GigabitEthernet, address is 0000.0000.0000 (bia 0000.0000.0000)")
                self.write_line("  " + ", ".join([vlan_membership(port), port_mode(port), port_state(port)]))
                if port.description:
                    self.write_line("  Port name is %s" % port.description)
                else:
                    self.write_line("  No port name")

    def show_vlan_brief(self):
        self.write_line("")
        self.write_line("VLAN     Name       Encap ESI                              Ve    Pri Ports")
        self.write_line("----     ----       ----- ---                              ----- --- -----")
        for vlan in sorted(self.switch_configuration.vlans, key=lambda v: v.number):
            ports = [port for port in self.switch_configuration.ports
                     if port.access_vlan == vlan.number or (port.access_vlan is None and vlan.number == 1)]
            self.write_line("%-4s     %-10s                                        -     -%s" % (
                vlan.number,
                vlan_name(vlan)[:10] if vlan_name(vlan) else "[None]",
                ("   Untagged Ports : %s" % to_port_ranges(ports)) if ports else ""
            ))

    def show_vlan_int(self, args):
        port = self.switch_configuration.get_port_by_partial_name(" ".join(args[1:]))
        if port:
            untagged_vlan = port.access_vlan or (port.trunk_native_vlan if port.trunk_native_vlan != 1 else None)
            if untagged_vlan is None and port.trunk_vlans is None:
                self.write_line("VLAN: 1  Untagged")
            else:
                for vlan in sorted(port.trunk_vlans or []):
                    if untagged_vlan is not None and untagged_vlan < vlan:
                        self.write_line("VLAN: %s  Untagged" % untagged_vlan)
                        untagged_vlan = None
                    self.write_line("VLAN: %s  Tagged" % vlan)

                if untagged_vlan is not None:
                    self.write_line("VLAN: %s  Untagged" % untagged_vlan)
        else:
            self.write_line("Invalid input -> %s" % args[2])
            self.write_line("Type ? for a list")

    def _show_vlan(self, vlan_id):
        vlan = self.switch_configuration.get_vlan(vlan_id)
        if vlan is None:
            self.write_line("Error: vlan {} is not configured".format(vlan_id))
        else:
            vif = self.get_interface_vlan_for(vlan)
            ports = self.get_interface_ports_for(vlan)

            self.write_line("")
            self.write_line("PORT-VLAN {}, Name {}, Priority Level -, Priority Force 0, Creation Type STATIC".format(
                vlan_id, vlan.name if vlan.name is not None else "[None]"))
            self.write_line("Topo HW idx    : 81    Topo SW idx: 257    Topo next vlan: 0")
            self.write_line("L2 protocols   : STP")
            if len(ports["tagged"]) > 0:
                self.write_line("Statically tagged Ports    : {}".format(to_port_ranges(ports["tagged"])))
            if len(ports["untagged"]) > 0:
                self.write_line("Untagged Ports : {}".format(to_port_ranges(ports["untagged"])))
            self.write_line("Associated Virtual Interface Id: {}".format(
                "NONE" if vif is None else vif.name.split(" ")[-1]))
            self.write_line("----------------------------------------------------------")
            if len(ports["untagged"]) == 0 and len(ports["tagged"]) == 0:
                self.write_line("No ports associated with VLAN")
            else:
                self.write_line("Port  Type      Tag-Mode  Protocol  State")
                for port in ports["untagged"]:
                    self.write_line("{}   PHYSICAL  UNTAGGED  STP       DISABLED".format(split_port_name(port.name)[1]))
                for port in ports["tagged"]:
                    self.write_line("{}   PHYSICAL  TAGGED    STP       DISABLED".format(split_port_name(port.name)[1]))

            self.write_line("Arp Inspection: 0")
            self.write_line("DHCP Snooping: 0")
            self.write_line("IPv4 Multicast Snooping: Disabled")
            self.write_line("IPv6 Multicast Snooping: Disabled")
            self.write_line("")

            if vif is None:
                self.write_line("No Virtual Interfaces configured for this vlan")
            else:
                self.write_line("Ve{} is down, line protocol is down".format(vif.name.split(" ")[-1]))
                self.write_line("  Type is Vlan (Vlan Id: {})".format(vlan_id))
                self.write_line("  Hardware is Virtual Ethernet, address is 748e.f8a7.1b01 (bia 748e.f8a7.1b01)")
                self.write_line("  No port name")
                self.write_line("  Vlan id: {}".format(vlan_id))
                self.write_line("  Internet address is 0.0.0.0/0, IP MTU 1500 bytes, encapsulation ethernet")
                self.write_line("  Configured BW 0 kbps")

    def get_interface_vlan_for(self, vlan):
        return next((p for p in self.switch_configuration.ports
                     if isinstance(p, VlanPort) and p.vlan_id == vlan.number),
                    None)

    def show_version(self):
        self.write_line("System: NetIron CER (Serial #: 1P2539K036,  Part #: 40-1000617-02)")
        self.write_line("License: RT_SCALE, ADV_SVCS_PREM (LID: XXXXXXXXXX)")
        self.write_line("Boot     : Version 5.8.0T185 Copyright (c) 1996-2014 Brocade Communications Systems, Inc.")
        self.write_line("Compiled on May 18 2015 at 13:03:00 labeled as ceb05800")
        self.write_line(" (463847 bytes) from boot flash")
        self.write_line("Monitor  : Version 5.8.0T185 Copyright (c) 1996-2014 Brocade Communications Systems, Inc.")
        self.write_line("Compiled on May 18 2015 at 13:03:00 labeled as ceb05800")
        self.write_line(" (463847 bytes) from code flash")
        self.write_line("IronWare : Version 5.8.0bT183 Copyright (c) 1996-2014 Brocade Communications Systems, Inc.")
        self.write_line("Compiled on May 21 2015 at 09:20:22 labeled as ce05800b")
        self.write_line(" (17563175 bytes) from Primary")
        self.write_line("CPLD Version: 0x00000010")
        self.write_line("Micro-Controller Version: 0x0000000d")
        self.write_line("Extended route scalability")
        self.write_line("PBIF Version: 0x0162")
        self.write_line("800 MHz Power PC processor 8544 (version 8021/0023) 400 MHz bus")
        self.write_line("512 KB Boot Flash (MX29LV040C), 64 MB Code Flash (MT28F256J3)")
        self.write_line("2048 MB DRAM")
        self.write_line("System uptime is 109 days 4 hours 39 minutes 4 seconds")

    def get_interface_ports_for(self, vlan):
        vlan_ports = {"tagged": [], "untagged": []}
        for port in self.switch_configuration.ports:
            if not isinstance(port, VlanPort):
                if port.access_vlan == vlan.number or port.trunk_native_vlan == vlan.number:
                    vlan_ports["untagged"].append(port)
                elif port.trunk_vlans and vlan.number in port.trunk_vlans:
                    vlan_ports["tagged"].append(port)
        return vlan_ports class ShellSession(object):
    def __init__(self, command_processor):
        self.command_processor = command_processor

        self.command_processor.show_prompt()

    def receive(self, line):
        self.command_processor.logger.debug("received: %s" % line)
        try:
            processed = self.command_processor.process_command(line)
        except TerminalExitSignal:
            return False

        if not processed:
            self.command_processor.logger.info("Command not supported : %s" % line)

            self.handle_unknown_command(line)

            self.command_processor.show_prompt()

        return not self.command_processor.is_done

    def handle_unknown_command(self, line):
        pass class Port(object):
    def __init__(self, name):
        self.name = name
        self.switch_configuration = None
        self.reset()

    def reset(self):
        self.description = None
        self.mode = None
        self.access_vlan = None
        self.trunk_vlans = None
        self.trunk_native_vlan = None
        self.trunk_encapsulation_mode = None
        self.shutdown = None
        self.vrf = None
        self.speed = None
        self.auto_negotiation = None
        self.aggregation_membership = None
        self.mtu = None
        self.vendor_specific = {}
        self.ip_helpers = []
        self.lldp_transmit = None
        self.lldp_receive = None
        self.lldp_med = None
        self.lldp_med_transmit_capabilities = None
        self.lldp_med_transmit_network_policy = None
        self.spanning_tree = None
        self.spanning_tree_portfast = None
        self.ntp = None

    def get_subname(self, length):
        name, number = split_port_name(self.name)
        return name[:length] + number
import logging
from fake_switches import switch_core
from fake_switches.brocade.command_processor.config import ConfigCommandProcessor
from fake_switches.brocade.command_processor.config_interface import ConfigInterfaceCommandProcessor
from fake_switches.brocade.command_processor.config_virtual_interface import ConfigVirtualInterfaceCommandProcessor
from fake_switches.brocade.command_processor.config_virtual_interface_vrrp import \
    ConfigVirtualInterfaceVrrpCommandProcessor
from fake_switches.brocade.command_processor.config_vlan import ConfigVlanCommandProcessor
from fake_switches.brocade.command_processor.config_vrf import ConfigVrfCommandProcessor
from fake_switches.brocade.command_processor.default import DefaultCommandProcessor
from fake_switches.brocade.command_processor.enabled import EnabledCommandProcessor
from fake_switches.brocade.command_processor.piping import PipingProcessor
from fake_switches.command_processing.shell_session import ShellSession
from fake_switches.switch_configuration import Port
from fake_switches.terminal import LoggingTerminalController
# Copyright 2015 Internap.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.




class BrocadeSwitchCore(switch_core.SwitchCore):
    def __init__(self, switch_configuration):
        super(BrocadeSwitchCore, self).__init__(switch_configuration)
        self.switch_configuration.add_vlan(self.switch_configuration.new("Vlan", 1))
        self.logger = None
        self.last_connection_id = 0

    def launch(self, protocol, terminal_controller):
        self.last_connection_id += 1

        self.logger = logging.getLogger(
            "fake_switches.brocade.%s.%s.%s" % (self.switch_configuration.name, self.last_connection_id, protocol))

        command_processor = DefaultCommandProcessor(
            enabled=EnabledCommandProcessor(
                config=ConfigCommandProcessor(
                    config_vlan=ConfigVlanCommandProcessor(),

                    config_vrf=ConfigVrfCommandProcessor(),