# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# 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.

import enum
from typing import Dict

OSU_TUNNEL_URL = '/restconf/data/ietf-te:tunnel'

class EndpointProtectionRoleEnum(enum.Enum):
    WORK = 'work'

class LspProtectionTypeEnum(enum.Enum):
    UNPROTECTED = 'ietf-te-types:lsp-protection-unprotected'

class LspRestorationTypeEnum(enum.Enum):
    NOT_APPLICABLE = 'ietf-te-types:lsp-restoration-not-applicable'

class TunnelAdminStateEnum(enum.Enum):
    UP = 'ietf-te-types:tunnel-admin-state-up'

class OduTypeEnum(enum.Enum):
    OSUFLEX = 'osuflex'

def compose_osu_tunnel_endpoint(
    node_id : str, tp_id : str, ttp_channel_name : str,
    protection_role : EndpointProtectionRoleEnum = EndpointProtectionRoleEnum.WORK
) -> Dict:
    return {
        'node-id': node_id, 'tp-id': tp_id, 'ttp-channel-name': ttp_channel_name,
        'protection-role': protection_role.value
    }

def compose_osu_tunnel_te_bandwidth_odu(odu_type : OduTypeEnum, number : int) -> Dict:
    return {'layer': 'odu', 'odu-type': odu_type.value, 'number': number}

def compose_osu_tunnel_protection(
    type_ : LspProtectionTypeEnum = LspProtectionTypeEnum.UNPROTECTED, reversion_disable : bool = True
) -> Dict:
    return {'protection-type': type_.value, 'protection-reversion-disable': reversion_disable}

def compose_osu_tunnel_restoration(
    type_ : LspRestorationTypeEnum = LspRestorationTypeEnum.NOT_APPLICABLE, restoration_lock : bool = False
) -> Dict:
    return {'restoration-type': type_.value, 'restoration-lock': restoration_lock}

def compose_osu_tunnel(
    name : str,
    src_node_id : str, src_tp_id : str, src_ttp_channel_name : str,
    dst_node_id : str, dst_tp_id : str, dst_ttp_channel_name : str,
    odu_type : OduTypeEnum, osuflex_number : int,
    delay : int, bidirectional : bool = True,
    admin_state : TunnelAdminStateEnum = TunnelAdminStateEnum.UP
) -> Dict:
    return {'ietf-te:tunnel': [{
        'name': name.lower(),
        'title': name.upper(),
        'admin-state': admin_state.value,
        'delay': delay,
        'te-bandwidth': compose_osu_tunnel_te_bandwidth_odu(odu_type, osuflex_number),
        'bidirectional': bidirectional,
        'source-endpoints': {'source-endpoint': [
            compose_osu_tunnel_endpoint(src_node_id, src_tp_id, src_ttp_channel_name),
        ]},
        'destination-endpoints': {'destination-endpoint': [
            compose_osu_tunnel_endpoint(dst_node_id, dst_tp_id, dst_ttp_channel_name),
        ]},
        'restoration': compose_osu_tunnel_restoration(),
        'protection': compose_osu_tunnel_protection(),
    }]}
