# -*- coding: utf-8 -*-

"""
Task 22.1d

Copy the Topology class from task 22.1c and modify it.

Add the add_link method, which adds the specified link if it is not already
in the topology. If the connection exists, print the message
"Such a connection already exists", If one of the sides is in the topology,
display the message "A link to one of the ports exists".

Topology creation:
In [7]: t = Topology(topology_example)

In [8]: t.topology
Out[8]:
{('R1', 'Eth0/0'): ('SW1', 'Eth0/1'),
 ('R2', 'Eth0/0'): ('SW1', 'Eth0/2'),
 ('R2', 'Eth0/1'): ('SW2', 'Eth0/11'),
 ('R3', 'Eth0/0'): ('SW1', 'Eth0/3'),
 ('R3', 'Eth0/1'): ('R4', 'Eth0/0'),
 ('R3', 'Eth0/2'): ('R5', 'Eth0/0')}

In [9]: t.add_link(('R1', 'Eth0/4'), ('R7', 'Eth0/0'))

In [10]: t.topology
Out[10]:
{('R1', 'Eth0/0'): ('SW1', 'Eth0/1'),
 ('R1', 'Eth0/4'): ('R7', 'Eth0/0'),
 ('R2', 'Eth0/0'): ('SW1', 'Eth0/2'),
 ('R2', 'Eth0/1'): ('SW2', 'Eth0/11'),
 ('R3', 'Eth0/0'): ('SW1', 'Eth0/3'),
 ('R3', 'Eth0/1'): ('R4', 'Eth0/0'),
 ('R3', 'Eth0/2'): ('R5', 'Eth0/0')}

In [11]: t.add_link(('R1', 'Eth0/4'), ('R7', 'Eth0/0'))
Such a connection already exists

In [12]: t.add_link(('R1', 'Eth0/4'), ('R7', 'Eth0/5'))
A link to one of the ports exists


"""

class Topology:
    def __init__(self, topology_dict):
        self.topology = self._normalize(topology_dict)

    def _normalize(self, topology_dict):
        normalized_topology = {}
        for box, neighbor in topology_dict.items():
            if not neighbor in normalized_topology:
                normalized_topology[box] = neighbor
        return normalized_topology

    def delete_link(self, from_port, to_port):
        if from_port in self.topology and self.topology[from_port] == to_port:
            del self.topology[from_port]
        elif to_port in self.topology and self.topology[to_port] == from_port:
            del self.topology[to_port]
        else:
            print("There is no such link")

    def delete_node(self, node):
        original_size = len(self.topology)
        for src, dest in list(self.topology.items()):
            if node in src or node in dest:
                del self.topology[src]
        if original_size == len(self.topology):
            print("There is no such device")

    def add_link(self, src, dest):
        keys_and_values = self.topology.keys() | self.topology.values()
        if self.topology.get(src) == dest:
            print("Such a connection already exists")
        elif src in keys_and_values or dest in keys_and_values:
            print("A link to one of the ports exists")
        else:
            self.topology[src] = dest
