# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# 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.

from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
from common.tools.object_factory.Context import json_context, json_context_id
from common.tools.object_factory.Device import (
    json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, json_device_id)
from common.tools.object_factory.Link import json_link, json_link_id
from common.tools.object_factory.Topology import json_topology, json_topology_id
from .Tools import get_link_uuid, json_endpoint_ids

# ----- Context --------------------------------------------------------------------------------------------------------
D1_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
D1_CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)

# ----- Topology -------------------------------------------------------------------------------------------------------
D1_TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=D1_CONTEXT_ID)
D1_TOPOLOGY    = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=D1_CONTEXT_ID)

# ----- Devices --------------------------------------------------------------------------------------------------------
# Assume all devices have the same architecture of endpoints
DEVICE_ENDPOINT_DEFS = [
    # Trunk ports
    ('1/1', '25Gbps', []), ('1/2', '25Gbps', []), ('1/3', '25Gbps', []), ('1/4', '25Gbps', []),
    # Inter-domain ports
    ('2/1', '100Gbps', []), ('2/2', '100Gbps', []),
    # Access ports
    ('3/1', '10Gbps', []), ('3/2', '10Gbps', []), ('3/3', '10Gbps', []), ('3/4', '10Gbps', []),
    ('3/5', '10Gbps', []), ('3/6', '10Gbps', []), ('3/7', '10Gbps', []), ('3/8', '10Gbps', []),
]

DEVICE_D1R1_UUID          = 'D1-R1'
DEVICE_D1R1_ID            = json_device_id(DEVICE_D1R1_UUID)
DEVICE_D1R1               = json_device_emulated_packet_router_disabled(DEVICE_D1R1_UUID)
DEVICE_D1R1_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_ENDPOINT_DEFS)

DEVICE_D1R2_UUID          = 'D1-R2'
DEVICE_D1R2_ID            = json_device_id(DEVICE_D1R2_UUID)
DEVICE_D1R2               = json_device_emulated_packet_router_disabled(DEVICE_D1R2_UUID)
DEVICE_D1R2_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_ENDPOINT_DEFS)

DEVICE_D1R3_UUID          = 'D1-R3'
DEVICE_D1R3_ID            = json_device_id(DEVICE_D1R3_UUID)
DEVICE_D1R3               = json_device_emulated_packet_router_disabled(DEVICE_D1R3_UUID)
DEVICE_D1R3_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_ENDPOINT_DEFS)

DEVICE_D1R4_UUID          = 'D1-R4'
DEVICE_D1R4_ID            = json_device_id(DEVICE_D1R4_UUID)
DEVICE_D1R4               = json_device_emulated_packet_router_disabled(DEVICE_D1R4_UUID)
DEVICE_D1R4_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_ENDPOINT_DEFS)

# Virtual devices on remote domains
DEVICE_D2R1_UUID          = 'D2-R1'
DEVICE_D2R1_ID            = json_device_id(DEVICE_D2R1_UUID)
DEVICE_D2R1               = json_device_emulated_packet_router_disabled(DEVICE_D2R1_UUID)
DEVICE_D2R1_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_ENDPOINT_DEFS)

ENDPOINT_IDS = {}
ENDPOINT_IDS.update(json_endpoint_ids(DEVICE_D1R1_ID, DEVICE_ENDPOINT_DEFS))
ENDPOINT_IDS.update(json_endpoint_ids(DEVICE_D1R2_ID, DEVICE_ENDPOINT_DEFS))
ENDPOINT_IDS.update(json_endpoint_ids(DEVICE_D1R3_ID, DEVICE_ENDPOINT_DEFS))
ENDPOINT_IDS.update(json_endpoint_ids(DEVICE_D1R4_ID, DEVICE_ENDPOINT_DEFS))
ENDPOINT_IDS.update(json_endpoint_ids(DEVICE_D2R1_ID, DEVICE_ENDPOINT_DEFS))


# ----- Links ----------------------------------------------------------------------------------------------------------
# Intra-domain links
LINK_D1R1_D1R2_UUID = get_link_uuid(ENDPOINT_IDS[DEVICE_D1R1_UUID]['1/2'], ENDPOINT_IDS[DEVICE_D1R2_UUID]['1/1'])
LINK_D1R1_D1R2_ID   = json_link_id(LINK_D1R1_D1R2_UUID)
LINK_D1R1_D1R2      = json_link(LINK_D1R1_D1R2_UUID, [
    ENDPOINT_IDS[DEVICE_D1R1_UUID]['1/2'], ENDPOINT_IDS[DEVICE_D1R2_UUID]['1/1']])

LINK_D1R2_D1R3_UUID = get_link_uuid(ENDPOINT_IDS[DEVICE_D1R2_UUID]['1/2'], ENDPOINT_IDS[DEVICE_D1R3_UUID]['1/1'])
LINK_D1R2_D1R3_ID   = json_link_id(LINK_D1R2_D1R3_UUID)
LINK_D1R2_D1R3      = json_link(LINK_D1R2_D1R3_UUID, [
    ENDPOINT_IDS[DEVICE_D1R2_UUID]['1/2'], ENDPOINT_IDS[DEVICE_D1R3_UUID]['1/1']])

LINK_D1R3_D1R4_UUID = get_link_uuid(ENDPOINT_IDS[DEVICE_D1R3_UUID]['1/2'], ENDPOINT_IDS[DEVICE_D1R4_UUID]['1/1'])
LINK_D1R3_D1R4_ID   = json_link_id(LINK_D1R3_D1R4_UUID)
LINK_D1R3_D1R4      = json_link(LINK_D1R3_D1R4_UUID, [
    ENDPOINT_IDS[DEVICE_D1R3_UUID]['1/2'], ENDPOINT_IDS[DEVICE_D1R4_UUID]['1/1']])

LINK_D1R4_D1R1_UUID = get_link_uuid(ENDPOINT_IDS[DEVICE_D1R4_UUID]['1/2'], ENDPOINT_IDS[DEVICE_D1R1_UUID]['1/1'])
LINK_D1R4_D1R1_ID   = json_link_id(LINK_D1R4_D1R1_UUID)
LINK_D1R4_D1R1      = json_link(LINK_D1R4_D1R1_UUID, [
    ENDPOINT_IDS[DEVICE_D1R4_UUID]['1/2'], ENDPOINT_IDS[DEVICE_D1R1_UUID]['1/1']])

# Inter-domain links
LINK_D1R4_D2R1_UUID = get_link_uuid(ENDPOINT_IDS[DEVICE_D1R4_UUID]['2/1'], ENDPOINT_IDS[DEVICE_D2R1_UUID]['2/1'])
LINK_D1R4_D2R1_ID   = json_link_id(LINK_D1R4_D2R1_UUID)
LINK_D1R4_D2R1      = json_link(LINK_D1R4_D2R1_UUID, [
    ENDPOINT_IDS[DEVICE_D1R4_UUID]['2/1'], ENDPOINT_IDS[DEVICE_D2R1_UUID]['2/1']])

# ----- Object Collections ---------------------------------------------------------------------------------------------

D1_CONTEXTS = [D1_CONTEXT]
D1_TOPOLOGIES = [D1_TOPOLOGY]

D1_DEVICES = [
    (DEVICE_D1R1, DEVICE_D1R1_CONNECT_RULES),
    (DEVICE_D1R2, DEVICE_D1R2_CONNECT_RULES),
    (DEVICE_D1R3, DEVICE_D1R3_CONNECT_RULES),
    (DEVICE_D1R4, DEVICE_D1R4_CONNECT_RULES),
    (DEVICE_D2R1, DEVICE_D2R1_CONNECT_RULES),
]

D1_LINKS = [
    LINK_D1R1_D1R2, LINK_D1R2_D1R3, LINK_D1R3_D1R4, LINK_D1R4_D1R1,
    LINK_D1R4_D2R1,
]
