# Distributed under the OpenFlow Software License (see LICENSE)
# Copyright (c) 2010 The Board of Trustees of The Leland Stanford Junior University
# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
"""
Flow stats test cases

These tests check the behavior of the flow stats request.
"""

import logging

from oftest import config
import oftest.base_tests as base_tests
import ofp
import oftest.packet as scapy

from oftest.testutils import *
from oftest.parse import parse_ipv6

class AllFlowStats(base_tests.SimpleDataPlane):
    """
    Retrieve all flows and verify the stats entries match the flow-mods sent
    """
    def runTest(self):
        port1, port2, port3 = openflow_ports(3)
        delete_all_flows(self.controller)

        flow1 = ofp.message.flow_add(
                table_id=0,
                priority=0x11,
                idle_timeout=0x21,
                hard_timeout=0x31,
                flags=ofp.OFPFF_NO_PKT_COUNTS,
                cookie=1,
                match=ofp.match([
                    ofp.oxm.in_port(port1),
                    ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|1)]),
                instructions=[
                    ofp.instruction.write_actions(
                        actions=[
                            ofp.action.output(
                                port=port1,
                                max_len=ofp.OFPCML_NO_BUFFER)])],
                buffer_id=ofp.OFP_NO_BUFFER)

        flow2 = ofp.message.flow_add(
                table_id=0,
                priority=0x12,
                idle_timeout=0x22,
                hard_timeout=0x32,
                flags=ofp.OFPFF_NO_BYT_COUNTS,
                cookie=2,
                match=ofp.match([
                    ofp.oxm.in_port(port2),
                    ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2)]),
                instructions=[
                    ofp.instruction.write_actions(
                        actions=[
                            ofp.action.output(
                                port=port2,
                                max_len=ofp.OFPCML_NO_BUFFER)])],
                buffer_id=ofp.OFP_NO_BUFFER)

        flow3 = ofp.message.flow_add(
                table_id=0,
                priority=0x13,
                idle_timeout=0x23,
                hard_timeout=0x33,
                flags=ofp.OFPFF_CHECK_OVERLAP,
                cookie=3,
                match=ofp.match([
                    ofp.oxm.in_port(port3),
                    ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|3)]),
                instructions=[
                    ofp.instruction.write_actions(
                        actions=[
                            ofp.action.output(
                                port=port3,
                                max_len=ofp.OFPCML_NO_BUFFER)])],
                buffer_id=ofp.OFP_NO_BUFFER)

        flows = [flow1, flow2, flow3]
        for flow in flows:
            logging.debug(flow.show())
            self.controller.message_send(flow)

        flows_by_cookie = { flow.cookie: flow for flow in flows }

        do_barrier(self.controller)

        logging.info("Sending flow stats request")
        stats = get_flow_stats(self, ofp.match())
        logging.info("Received %d flow stats entries", len(stats))

        seen_cookies = set()
        for entry in stats:
            logging.debug(entry.show())
            self.assertTrue(entry.cookie in flows_by_cookie, "Unexpected cookie")
            self.assertTrue(entry.cookie not in seen_cookies, "Duplicate cookie")
            flow = flows_by_cookie[entry.cookie]
            seen_cookies.add(entry.cookie)

            self.assertEqual(entry.table_id, flow.table_id)
            self.assertEqual(entry.priority, flow.priority)
            self.assertEqual(entry.idle_timeout, flow.idle_timeout)
            self.assertEqual(entry.hard_timeout, flow.hard_timeout)
            self.assertEqual(entry.flags, flow.flags)
            self.assertEqual(entry.cookie, flow.cookie)
            self.assertEqual(sorted(entry.match.oxm_list), sorted(flow.match.oxm_list))
            self.assertEqual(sorted(entry.instructions), sorted(flow.instructions))

        self.assertEqual(seen_cookies, set([1,2,3]))

class CookieFlowStats(base_tests.SimpleDataPlane):
    """
    Retrieve flows using various masks on the cookie
    """
    def runTest(self):
        delete_all_flows(self.controller)

        # Also used as masks
        cookies = [
            0x0000000000000000,
            0xDDDDDDDD00000000,
            0x00000000DDDDDDDD,
            0xDDDDDDDDDDDDDDDD,
            0xDDDD0000DDDD0000,
            0x0000DDDD0000DDDD,
            0xDD00DD00DD00DD00,
            0xD0D0D0D0D0D0D0D0,
            0xF000000000000000,
            0xFF00000000000000,
            0xFFF0000000000000,
            0xFFFF000000000000,
        ]

        # Generate the matching cookies for each combination of cookie and mask
        matches = {}
        for cookie in cookies:
            for mask in cookies:
                matching = []
                for cookie2 in cookies:
                    if cookie & mask == cookie2 & mask:
                        matching.append(cookie2)
                matches[(cookie, mask)] = sorted(matching)

        # Generate a flow for each cookie
        flows = {}
        for idx, cookie in enumerate(cookies):
            flows[cookie] = ofp.message.flow_add(
                table_id=0,
                cookie=cookie,
                match=ofp.match([ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|idx)]),
                buffer_id=ofp.OFP_NO_BUFFER)

        # Install flows
        for flow in flows.values():
            self.controller.message_send(flow)
        do_barrier(self.controller)

        # For each combination of cookie and match, verify the correct flows
        # are retrieved
        for (cookie, mask), expected_cookies in matches.items():
            stats = get_flow_stats(self, ofp.match(), cookie=cookie, cookie_mask=mask)
            received_cookies = sorted([entry.cookie for entry in stats])
            logging.debug("expected 0x%016x/0x%016x: %s", cookie, mask,
                          ' '.join(["0x%016x" % x for x in expected_cookies]))
            logging.debug("received 0x%016x/0x%016x: %s", cookie, mask,
                          ' '.join(["0x%016x" % x for x in received_cookies]))
            self.assertEqual(expected_cookies, received_cookies)
