# Copyright 2017-present Open Networking Foundation
#
# 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 unittest import main
from nose.tools import nottest

from tests.utests.voltha.core.flow_helpers import FlowHelpers
from voltha.core.flow_decomposer import *
from voltha.protos import third_party
from voltha.protos.device_pb2 import Device, Port
from voltha.protos.logical_device_pb2 import LogicalPort


class TestFlowDecomposer(FlowHelpers, FlowDecomposer):

    def setUp(self):
        self.logical_device_id = 'pon'
        self._nni_logical_port_no = None

    # methods needed by FlowDecomposer; faking real lookups

    _devices = {
        'olt':  Device(
            id='olt',
            root=True,
            parent_id='logical_device',
            ports=[
                Port(port_no=1, label='pon'),
                Port(port_no=2, label='nni'),
            ]
        ),
        'onu1': Device(
            id='onu1',
            parent_id='olt',
            ports=[
                Port(port_no=1, label='pon'),
                Port(port_no=2, label='uni'),
            ]
        ),
        'onu2': Device(
            id='onu2',
            parent_id='olt',
            ports=[
                Port(port_no=1, label='pon'),
                Port(port_no=2, label='uni'),
            ]
        ),
        'onu3': Device(
            id='onu3',
            parent_id='olt',
            ports=[
                Port(port_no=1, label='pon'),
                Port(port_no=2, label='uni'),
            ]
        ),
        'onu4': Device(
            id='onu4',
            parent_id='olt',
            ports=[
                Port(port_no=1, label='pon'),
                Port(port_no=2, label='uni'),
            ]
        ),
    }

    _logical_ports = {
        0: LogicalPort(id='0', device_id='olt', device_port_no=2),
        1: LogicalPort(id='1', device_id='onu1', device_port_no=2),
        2: LogicalPort(id='2', device_id='onu2', device_port_no=2),
        3: LogicalPort(id='3', device_id='onu3', device_port_no=2),
        4: LogicalPort(id='4', device_id='onu4', device_port_no=2),
    }

    def get_wildcard_input_ports(self, exclude_port=None):
        logical_ports =  self._logical_ports.iterkeys()
        return [port_no for port_no in logical_ports
                if port_no != exclude_port]

    _routes = {

        # DOWNSTREAM ROUTES

        (0, 1): [
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[1],
                     _devices['olt'].ports[0]),
            RouteHop(_devices['onu1'],
                     _devices['onu1'].ports[0],
                     _devices['onu1'].ports[1]),
        ],
        (0, 2): [
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[1],
                     _devices['olt'].ports[0]),
            RouteHop(_devices['onu2'],
                     _devices['onu2'].ports[0],
                     _devices['onu2'].ports[1]),
        ],
        (0, 3): [
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[1],
                     _devices['olt'].ports[0]),
            RouteHop(_devices['onu3'],
                     _devices['onu3'].ports[0],
                     _devices['onu3'].ports[1]),
        ],
        (0, 4): [
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[1],
                     _devices['olt'].ports[0]),
            RouteHop(_devices['onu4'],
                     _devices['onu4'].ports[0],
                     _devices['onu4'].ports[1]),
        ],

        # UPSTREAM DATA PLANE

        (1, 0): [
            RouteHop(_devices['onu1'],
                     _devices['onu1'].ports[1],
                     _devices['onu1'].ports[0]),
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]),
        ],
        (2, 0): [
            RouteHop(_devices['onu2'],
                     _devices['onu2'].ports[1],
                     _devices['onu2'].ports[0]),
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]),
        ],
        (3, 0): [
            RouteHop(_devices['onu3'],
                     _devices['onu3'].ports[1],
                     _devices['onu3'].ports[0]),
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]),
        ],
        (4, 0): [
            RouteHop(_devices['onu4'],
                     _devices['onu4'].ports[1],
                     _devices['onu4'].ports[0]),
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]),
        ],

        # UPSTREAM NEXT TABLE BASED

        (1, None): [
            RouteHop(_devices['onu1'],
                     _devices['onu1'].ports[1],
                     _devices['onu1'].ports[0]),
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]),
        ],
        (2, None): [
            RouteHop(_devices['onu2'],
                     _devices['onu2'].ports[1],
                     _devices['onu2'].ports[0]),
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]),
        ],
        (3, None): [
            RouteHop(_devices['onu3'],
                     _devices['onu3'].ports[1],
                     _devices['onu3'].ports[0]),
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]),
        ],
        (4, None): [
            RouteHop(_devices['onu4'],
                     _devices['onu4'].ports[1],
                     _devices['onu4'].ports[0]),
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]),
        ],

        # DOWNSTREAM NEXT TABLE BASED

        (0, None): [
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[1],
                     _devices['olt'].ports[0]),
            None  # 2nd hop is not known yet
        ],

        # UPSTREAM WILD-CARD
        (None, 0): [
            None,  # 1st hop is wildcard
            RouteHop(_devices['olt'],
                     _devices['olt'].ports[0],
                     _devices['olt'].ports[1]
                     )
        ]
    }

    _default_rules = {
        'onu1': (
            OrderedDict((f.id, f) for f in [
                mk_flow_stat(
                    match_fields=[
                        in_port(2),
                        vlan_vid(ofp.OFPVID_PRESENT | 0)
                    ],
                    actions=[
                        set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)),
                        output(1)
                    ]
                )
            ]),
            OrderedDict()
        ),
        'onu2': (
            OrderedDict((f.id, f) for f in [
                mk_flow_stat(
                    match_fields=[
                        in_port(2),
                        vlan_vid(ofp.OFPVID_PRESENT | 0)
                    ],
                    actions=[
                        set_field(vlan_vid(ofp.OFPVID_PRESENT | 102)),
                        output(1)
                    ]
                )
            ]),
            OrderedDict()
        ),
        'onu3': (
            OrderedDict((f.id, f) for f in [
                mk_flow_stat(
                    match_fields=[
                        in_port(2),
                        vlan_vid(ofp.OFPVID_PRESENT | 0)
                    ],
                    actions=[
                        set_field(vlan_vid(ofp.OFPVID_PRESENT | 103)),
                        output(1)
                    ]
                )
            ]),
            OrderedDict()
        ),
        'onu4': (
            OrderedDict((f.id, f) for f in [
                mk_flow_stat(
                    match_fields=[
                        in_port(2),
                        vlan_vid(ofp.OFPVID_PRESENT | 0)
                    ],
                    actions=[
                        set_field(vlan_vid(ofp.OFPVID_PRESENT | 104)),
                        output(1)
                    ]
                )
            ]),
            OrderedDict()
        )
    }

    def get_all_default_rules(self):
        return self._default_rules

    def get_default_rules(self, device_id):
        return self._default_rules[device_id]

    def get_route(self, in_port_no, out_port_no):
        if out_port_no is not None and \
                        (out_port_no & 0x7fffffff) == ofp.OFPP_CONTROLLER:
            # treat it as if the output port is the NNI of the OLT
            out_port_no = 0  # OLT NNI port
        return self._routes[(in_port_no, out_port_no)]

    # ~~~~~~~~~~~~~~~~~~~~~~~~ ACTUAL TEST CASES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    def test_eapol_reroute_rule_decomposition(self):
        flow = mk_flow_stat(
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 0),
                eth_type(0x888e)
            ],
            actions=[
                output(ofp.OFPP_CONTROLLER)
            ],
            priority=1000
        )
        device_rules = self.decompose_rules([flow], [])
        onu1_flows, onu1_groups = device_rules['onu1']
        olt_flows, olt_groups = device_rules['olt']
        self.assertEqual(len(onu1_flows), 1)
        self.assertEqual(len(onu1_groups), 0)
        self.assertEqual(len(olt_flows), 2)
        self.assertEqual(len(olt_groups), 0)
        self.assertFlowsEqual(onu1_flows.values()[0], mk_flow_stat(
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 0),
            ],
            actions=[
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)),
                output(1)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[0], mk_flow_stat(
            priority=1000,
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 1),
                eth_type(0x888e)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)),
                output(2)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[1], mk_flow_stat(
            priority=1000,
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 4000),
                vlan_pcp(0),
                metadata(1)
            ],
            actions=[
                pop_vlan(),
                output(1)
            ]
        ))

    def test_dhcp_reroute_rule_decomposition(self):
        flow = mk_flow_stat(
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 0),
                eth_type(0x0800),
                ipv4_dst(0xffffffff),
                ip_proto(17),
                udp_src(68),
                udp_dst(67)
            ],
            actions=[output(ofp.OFPP_CONTROLLER)],
            priority=1000
        )
        device_rules = self.decompose_rules([flow], [])
        onu1_flows, onu1_groups = device_rules['onu1']
        olt_flows, olt_groups = device_rules['olt']
        self.assertEqual(len(onu1_flows), 1)
        self.assertEqual(len(onu1_groups), 0)
        self.assertEqual(len(olt_flows), 2)
        self.assertEqual(len(olt_groups), 0)
        self.assertFlowsEqual(onu1_flows.values()[0], mk_flow_stat(
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 0),
            ],
            actions=[
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)),
                output(1)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[0], mk_flow_stat(
            priority=1000,
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 1),
                eth_type(0x0800),
                ipv4_dst(0xffffffff),
                ip_proto(17),
                udp_src(68),
                udp_dst(67)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)),
                output(2)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[1], mk_flow_stat(
            priority=1000,
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 4000),
                vlan_pcp(0),
                metadata(1)
            ],
            actions=[
                pop_vlan(),
                output(1)
            ]
        ))

    @nottest
    def test_igmp_reroute_rule_decomposition(self):
        flow = mk_flow_stat(
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 0),
                eth_type(0x0800),
                ip_proto(2)
            ],
            actions=[output(ofp.OFPP_CONTROLLER)],
            priority=1000
        )
        device_rules = self.decompose_rules([flow], [])
        onu1_flows, onu1_groups = device_rules['onu1']
        olt_flows, olt_groups = device_rules['olt']
        self.assertEqual(len(onu1_flows), 2)
        self.assertEqual(len(onu1_groups), 0)
        self.assertEqual(len(olt_flows), 2)
        self.assertEqual(len(olt_groups), 0)
        self.assertFlowsEqual(onu1_flows.values()[0], mk_flow_stat(
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 0),
            ],
            actions=[
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)),
                output(1)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[0], mk_flow_stat(
            priority=1000,
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 1),
                eth_type(0x0800),
                ip_proto(2)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)),
                output(2)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[1], mk_flow_stat(
            priority=1000,
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 4000),
                vlan_pcp(0),
                metadata(1)
            ],
            actions=[
                pop_vlan(),
                output(1)
            ]
        ))

    @nottest
    def test_wildcarded_igmp_reroute_rule_decomposition(self):
        flow = mk_flow_stat(
            match_fields=[
                eth_type(0x0800),
                ip_proto(2)
            ],
            actions=[output(ofp.OFPP_CONTROLLER)],
            priority=2000,
            cookie=140
        )
        device_rules = self.decompose_rules([flow], [])
        onu1_flows, onu1_groups = device_rules['onu1']
        olt_flows, olt_groups = device_rules['olt']
        self.assertEqual(len(onu1_flows), 1)
        self.assertEqual(len(onu1_groups), 0)
        self.assertEqual(len(olt_flows), 8)
        self.assertEqual(len(olt_groups), 0)
        self.assertFlowsEqual(onu1_flows.values()[0], mk_flow_stat(
            match_fields=[
                in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0)
            ],
            actions=[
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)),
                output(1)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[0], mk_flow_stat(
            priority=2000,
            cookie=140,
            match_fields=[
                in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 0),
                eth_type(0x0800), ip_proto(2)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)),
                output(2)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[1], mk_flow_stat(
            priority=2000,
            match_fields=[
                in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000),
                vlan_pcp(0), metadata(0)
            ],
            actions=[
                pop_vlan(), output(1)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[2], mk_flow_stat(
            priority=2000,
            cookie=140,
            match_fields=[
                in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 1),
                eth_type(0x0800), ip_proto(2)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)),
                output(2)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[3], mk_flow_stat(
            priority=2000,
            match_fields=[
                in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000),
                vlan_pcp(0), metadata(1)
            ],
            actions=[
                pop_vlan(), output(1)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[4], mk_flow_stat(
            priority=2000,
            cookie=140,
            match_fields=[
                in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 3),
                eth_type(0x0800), ip_proto(2)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)),
                output(2)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[5], mk_flow_stat(
            priority=2000,
            match_fields=[
                in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000),
                vlan_pcp(0), metadata(3)
            ],
            actions=[
                pop_vlan(), output(1)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[6], mk_flow_stat(
            priority=2000,
            cookie=140,
            match_fields=[
                in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 4),
                eth_type(0x0800), ip_proto(2)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)),
                output(2)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[7], mk_flow_stat(
            priority=2000,
            match_fields=[
                in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000),
                vlan_pcp(0), metadata(4)
            ],
            actions=[
                pop_vlan(), output(1)
            ]
        ))

    def test_unicast_upstream_rule_decomposition(self):
        flow1 = mk_flow_stat(
            priority=500,
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 0),
                vlan_pcp(0)
            ],
            actions=[
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)),
            ],
            next_table_id=1
        )
        flow2 = mk_flow_stat(
            priority=500,
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 101),
                vlan_pcp(0)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 1000)),
                set_field(vlan_pcp(0)),
                output(0)
            ]
        )
        device_rules = self.decompose_rules([flow1, flow2], [])
        onu1_flows, onu1_groups = device_rules['onu1']
        olt_flows, olt_groups = device_rules['olt']
        self.assertEqual(len(onu1_flows), 2)
        self.assertEqual(len(onu1_groups), 0)
        self.assertEqual(len(olt_flows), 1)
        self.assertEqual(len(olt_groups), 0)
        self.assertFlowsEqual(onu1_flows.values()[1], mk_flow_stat(
            priority=500,
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 0),
                vlan_pcp(0)
            ],
            actions=[
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)),
                output(1)
            ]
        ))
        self.assertFlowsEqual(olt_flows.values()[0], mk_flow_stat(
            priority=500,
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 101),
                vlan_pcp(0)
            ],
            actions=[
                push_vlan(0x8100),
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 1000)),
                set_field(vlan_pcp(0)),
                output(2)
            ]
        ))

    def test_unicast_downstream_rule_decomposition(self):
        flow1 = mk_flow_stat(
            match_fields=[
                in_port(0),
                vlan_vid(ofp.OFPVID_PRESENT | 1000),
                vlan_pcp(0)
            ],
            actions=[
                pop_vlan(),
            ],
            next_table_id=1,
            priority=500
        )
        flow2 = mk_flow_stat(
            match_fields=[
                in_port(0),
                vlan_vid(ofp.OFPVID_PRESENT | 101),
                vlan_pcp(0)
            ],
            actions=[
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 0)),
                output(1)
            ],
            priority=500
        )
        device_rules = self.decompose_rules([flow1, flow2], [])
        onu1_flows, onu1_groups = device_rules['onu1']
        olt_flows, olt_groups = device_rules['olt']
        self.assertEqual(len(onu1_flows), 2)
        self.assertEqual(len(onu1_groups), 0)
        self.assertEqual(len(olt_flows), 1)
        self.assertEqual(len(olt_groups), 0)
        self.assertFlowsEqual(olt_flows.values()[0], mk_flow_stat(
            priority=500,
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 1000),
                vlan_pcp(0)
            ],
            actions=[
                pop_vlan(),
                output(1)
            ]
        ))
        self.assertFlowsEqual(onu1_flows.values()[1], mk_flow_stat(
            priority=500,
            match_fields=[
                in_port(1),
                vlan_vid(ofp.OFPVID_PRESENT | 101),
                vlan_pcp(0)
            ],
            actions=[
                set_field(vlan_vid(ofp.OFPVID_PRESENT | 0)),
                output(2)
            ]
        ))

    def test_multicast_downstream_rule_decomposition(self):
        flow = mk_flow_stat(
            match_fields=[
                in_port(0),
                vlan_vid(ofp.OFPVID_PRESENT | 170),
                vlan_pcp(0),
                eth_type(0x800),
                ipv4_dst(0xe00a0a0a)
            ],
            actions=[
                group(10)
            ],
            priority=500
        )
        grp = mk_group_stat(
            group_id=10,
            buckets=[
                ofp.ofp_bucket(actions=[
                    pop_vlan(),
                    output(1)
                ])
            ]
        )
        device_rules = self.decompose_rules([flow], [grp])
        onu1_flows, onu1_groups = device_rules['onu1']
        olt_flows, olt_groups = device_rules['olt']
        self.assertEqual(len(onu1_flows), 2)
        self.assertEqual(len(onu1_groups), 0)
        self.assertEqual(len(olt_flows), 1)
        self.assertEqual(len(olt_groups), 0)
        self.assertFlowsEqual(olt_flows.values()[0], mk_flow_stat(
            priority=500,
            match_fields=[
                in_port(2),
                vlan_vid(ofp.OFPVID_PRESENT | 170),
                vlan_pcp(0),
                eth_type(0x800),
                ipv4_dst(0xe00a0a0a)
            ],
            actions=[
                pop_vlan(),
                output(1)
            ]
        ))
        self.assertFlowsEqual(onu1_flows.values()[1], mk_flow_stat(
            priority=500,
            match_fields=[
                in_port(1),
                eth_type(0x800),
                ipv4_dst(0xe00a0a0a)
            ],
            actions=[
                output(2)
            ]
        ))


if __name__ == '__main__':
    main()
