# 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
import random

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,
        ]

        for i in range(0, 10):
            cookies.append(random.getrandbits(64))

        # Generate the matching cookies for each combination of cookie and mask
        matches = {}
        for mask in cookies:
            for cookie 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.iteritems():
            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)
