#!/usr/bin/env python
# Copyright 2013, Big Switch Networks, Inc.
#
# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
# the following special exception:
#
# LOXI Exception
#
# As a special exception to the terms of the EPL, you may distribute libraries
# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
# that copyright and licensing notices generated by LoxiGen are not altered or removed
# from the LoxiGen Libraries and the notice provided below is (i) included in
# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
# documentation for the LoxiGen Libraries, if distributed in binary form.
#
# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
#
# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
# a copy of the EPL at:
#
# http://www.eclipse.org/legal/epl-v10.html
#
# 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
# EPL for the specific language governing permissions and limitations
# under the EPL.

import sys
import os
import unittest

root_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
sys.path.insert(0, root_dir)

import loxi_front_end.parser as parser
import loxi_front_end.frontend as frontend
from loxi_ir import *

class FrontendTests(unittest.TestCase):
    maxDiff = None

    def test_simple(self):
        ast = parser.parse("""
#version 1

enum ofp_port_config {
    OFPPC_PORT_DOWN = 0x1,
    OFPPC_NO_STP = 0x2,
    OFPPC_NO_RECV = 0x4,
    OFPPC_NO_RECV_STP = 0x8,
    OFPPC_NO_FLOOD = 0x10,
    OFPPC_NO_FWD = 0x20,
    OFPPC_NO_PACKET_IN = 0x40,
};

#version 2

struct of_echo_reply {
    uint8_t version;
    uint8_t type == 3;
    uint16_t length;
    uint32_t xid;
    of_octets_t data;
};

enum ofp_queue_op_failed_code {
    OFPQOFC_BAD_PORT = 0,
    OFPQOFC_BAD_QUEUE = 1,
    OFPQOFC_EPERM = 2,
};

struct of_packet_queue {
    uint32_t queue_id;
    uint16_t len;
    pad(2);
    list(of_queue_prop_t) properties;
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],
            ['enum', 'ofp_port_config', [], [
                ['OFPPC_PORT_DOWN', [], 1],
                ['OFPPC_NO_STP', [], 2],
                ['OFPPC_NO_RECV', [], 4],
                ['OFPPC_NO_RECV_STP', [], 8],
                ['OFPPC_NO_FLOOD', [], 16],
                ['OFPPC_NO_FWD', [], 32],
                ['OFPPC_NO_PACKET_IN', [], 64]]],
            ['metadata', 'version', '2'],
            ['struct', 'of_echo_reply', [], None, [
                ['data', 'uint8_t', 'version'],
                ['type', 'uint8_t', 'type', 3],
                ['data', 'uint16_t', 'length'],
                ['data', 'uint32_t', 'xid'],
                ['data', 'of_octets_t', 'data']]],
            ['enum', 'ofp_queue_op_failed_code', [], [
                ['OFPQOFC_BAD_PORT', [], 0],
                ['OFPQOFC_BAD_QUEUE', [], 1],
                ['OFPQOFC_EPERM', [], 2]]],
            ['struct', 'of_packet_queue', [], None, [
                ['data', 'uint32_t', 'queue_id'],
                ['data', 'uint16_t', 'len'],
                ['pad', 2],
                ['data', 'list(of_queue_prop_t)', 'properties']]],
        ]
        self.assertEquals(expected_ast, ast)

        ofinput = frontend.create_ofinput(ast)
        self.assertEquals(set([1, 2]), ofinput.wire_versions)
        expected_classes = [
            OFClass(name='of_echo_reply', superclass=None, members=[
                OFDataMember('version', 'uint8_t'), # XXX
                OFTypeMember('type', 'uint8_t', 3),
                OFLengthMember('length', 'uint16_t'),
                OFDataMember('xid', 'uint32_t'),
                OFDataMember('data', 'of_octets_t')], virtual=False, params={}),
            OFClass(name='of_packet_queue', superclass=None, members=[
                OFDataMember('queue_id', 'uint32_t'),
                OFLengthMember('len', 'uint16_t'),
                OFPadMember(2),
                OFDataMember('properties', 'list(of_queue_prop_t)')], virtual=False, params={}),
        ]
        self.assertEquals(expected_classes, ofinput.classes)
        expected_enums = [
            OFEnum(name='ofp_port_config', entries=[
                OFEnumEntry('OFPPC_PORT_DOWN', 1, {}),
                OFEnumEntry('OFPPC_NO_STP', 2, {}),
                OFEnumEntry('OFPPC_NO_RECV', 4, {}),
                OFEnumEntry('OFPPC_NO_RECV_STP', 8, {}),
                OFEnumEntry('OFPPC_NO_FLOOD', 16, {}),
                OFEnumEntry('OFPPC_NO_FWD', 32, {}),
                OFEnumEntry('OFPPC_NO_PACKET_IN', 64, {})], params={}),
            OFEnum(name='ofp_queue_op_failed_code', entries=[
                OFEnumEntry('OFPQOFC_BAD_PORT', 0, {}),
                OFEnumEntry('OFPQOFC_BAD_QUEUE', 1, {}),
                OFEnumEntry('OFPQOFC_EPERM', 2, {})], params={}),
        ]
        self.assertEquals(expected_enums, ofinput.enums)

    def test_inheritance(self):
        ast = parser.parse("""
#version 1

struct of_queue_prop {
    uint16_t type == ?;
    uint16_t len;
    pad(4);
};

struct of_queue_prop_min_rate : of_queue_prop {
    uint16_t type == 1;
    uint16_t len;
    pad(4);
    uint16_t rate;
    pad(6);
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],

            ['struct', 'of_queue_prop', [], None, [
                ['discriminator', 'uint16_t', 'type'],
                ['data', 'uint16_t', 'len'],
                ['pad', 4]]],

            ['struct', 'of_queue_prop_min_rate', [], 'of_queue_prop', [
                ['type', 'uint16_t', 'type', 1],
                ['data', 'uint16_t', 'len'],
                ['pad', 4],
                ['data', 'uint16_t', 'rate'],
                ['pad', 6]]],
        ]
        self.assertEquals(expected_ast, ast)

        ofinput = frontend.create_ofinput(ast)
        expected_classes = [
            OFClass(name='of_queue_prop', superclass=None, members=[
                OFDiscriminatorMember('type', 'uint16_t'),
                OFLengthMember('len', 'uint16_t'),
                OFPadMember(4)], virtual=True, params={}),
            OFClass(name='of_queue_prop_min_rate', superclass='of_queue_prop', members= [
                OFTypeMember('type', 'uint16_t', 1),
                OFLengthMember('len', 'uint16_t'),
                OFPadMember(4),
                OFDataMember('rate', 'uint16_t'),
                OFPadMember(6)], virtual=False, params= {}),
        ]
        self.assertEquals(expected_classes, ofinput.classes)

if __name__ == '__main__':
    unittest.main()
