routeros['/ip/dns'] = {
    'servers': '8.8.8.8',
}

for service in (
    'api-ssl',  # slow :(
    'ftp',  # we can download files via HTTP
    'telnet',
    'www-ssl',  # slow :(
    'winbox',
):
    routeros[f'/ip/service?name={service}'] = {
        'disabled': True,
    }

for service in (
    'api',
    'ssh',
    'www',
):
    routeros[f'/ip/service?name={service}'] = {
        'disabled': False,
    }

LOGGING_TOPICS = (
    'critical',
    'error',
    'info',
    'stp',
    'warning',
)

for topic in LOGGING_TOPICS:
    routeros[f'/system/logging?action=memory&topics={topic}'] = {}

if node.metadata.get('routeros/syslog-server', None):
    routeros['/system/logging/action?name=remote'] = {
        'target': 'remote',
        'remote': node.metadata.get('routeros/syslog-server'),
        'remote-port': 514,
    }
    for topic in LOGGING_TOPICS:
        routeros[f'/system/logging?action=remote&topics={topic}'] = {}

routeros['/snmp'] = {
    'enabled': True,
}
routeros['/snmp/community?name=public'] = {
    'addresses': '::/0',
    'disabled': False,
    'read-access': True,
    'write-access': False,
}

routeros['/system/clock'] = {
    'time-zone-autodetect': False,
    'time-zone-name': 'UTC',
}

routeros['/system/identity'] = {
    'name': node.name,
    # doing this first gives us some chance to notice an IP mixup
    'before': {'routeros:'},
}

routeros['/system/ntp/client'] = {
    'enabled': True,
    'server-dns-names': 'de.pool.ntp.org',
}

if node.metadata.get('routeros/gateway'):
    routeros['/ip/route?dst-address=0.0.0.0/0'] = {
        'gateway': node.metadata.get('routeros/gateway'),
    }

routeros['/interface/bridge?name=bridge'] = {
    'priority': node.metadata.get('routeros/bridge_priority', '0x8000'),
    'protocol-mode': 'rstp',
    'vlan-filtering': True,
}

# assign bridge ports
for port_name, port_conf in node.metadata.get('routeros/ports').items():
    if port_conf.get('delete'):
        routeros[f'/interface/bridge/port?interface={port_name}'] = {
            'delete': True,
            'tags': {'routeros-port'},
            'needs': {f'routeros:/interface?name={port_name}'},
        }
    else:
        pvid = port_conf.get('pvid')
        if not pvid:
            for vlan_name, vlan_conf in node.metadata.get('routeros/vlans').items():
                if port_name in vlan_conf.get('untagged', []):
                    if pvid:
                        raise ValueError(
                            f"{node.name}: port {port_name} untagged "
                            f"in VLANs {pvid} and {vlan_conf['id']}"
                        )
                    else:
                        pvid = vlan_conf['id']

        # Field must not be present of some port types.
        if port_conf.get('hw'):
            hw = {'hw': port_conf['hw']}
        else:
            hw = {}

        routeros[f'/interface/bridge/port?interface={port_name}'] = {
            'bridge': 'bridge',
            '_comment': port_conf.get('description', ''),
            'disabled': False,
            **hw,
            'pvid': pvid or '1',
            'tags': {'routeros-port'},
            'needs': {
                f'routeros:/interface?name={port_name}',
                'routeros:/interface/bridge?name=bridge',
                'tag:routeros-bridge-vlan',  # or we end up with dynamic VLANs after setting pvid to an unknown VLAN
            },
        }

    routeros[f'/interface?name={port_name}'] = {
        '_comment': port_conf.get('description', ''),
        'disabled': port_conf.get('disabled', False)
        and not port_conf.get('delete', False),
    }


# create IPs
for ip, ip_conf in node.metadata.get('routeros/ips').items():
    routeros[f'/ip/address?address={ip}'] = {
        'interface': ip_conf['interface'],
        'tags': {'routeros-ip'},
        'needs': {
            'tag:routeros-vlan',
        },
    }

for vlan, conf in node.metadata.get('routeros/vlans').items():
    if conf['delete']:
        # delete old VLANs
        routeros[f'/interface/vlan?name={vlan}'] = {
            'delete': True,
        }

        routeros[f"/interface/bridge/vlan?vlan-ids={conf['id']}"] = {
            'delete': True,
        }
    else:
        # create vlans
        routeros[f'/interface/vlan?name={vlan}'] = {
            'vlan-id': conf['id'],
            'interface': 'bridge',
            'tags': {'routeros-vlan'},
            'needs': {
                'routeros:/interface/bridge?name=bridge',
            },
        }

        # assign ports to vlans
        routeros[f"/interface/bridge/vlan?vlan-ids={conf['id']}"] = {
            'bridge': 'bridge',
            'untagged': sorted(conf['untagged']),
            'tagged': sorted(conf['tagged']),
            '_comment': vlan,
            'tags': {'routeros-bridge-vlan'},
            'needs': {
                'routeros:/interface/bridge?name=bridge',
                'tag:routeros-vlan',
            },
        }
