#!/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(align=8) {
    uint8_t version;
    uint8_t type == 3;
    uint16_t length;
    uint32_t xid;
    of_octets_t data;
};

enum ofp_queue_op_failed_code(wire_type=uint32, bitmask=False, complete=True) {
    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', [['align', '8']], None, [
                ['data', ['scalar', 'uint8_t'], 'version'],
                ['type', ['scalar', 'uint8_t'], 'type', 3],
                ['data', ['scalar', 'uint16_t'], 'length'],
                ['data', ['scalar', 'uint32_t'], 'xid'],
                ['data', ['scalar', 'of_octets_t'], 'data']]],
            ['enum', 'ofp_queue_op_failed_code',
                [['wire_type', 'uint32'], ['bitmask','False'], ['complete', 'True']], [
                ['OFPQOFC_BAD_PORT', [], 0],
                ['OFPQOFC_BAD_QUEUE', [], 1],
                ['OFPQOFC_EPERM', [], 2]]],
            ['struct', 'of_packet_queue', [], None, [
                ['data', ['scalar', 'uint32_t'], 'queue_id'],
                ['data', ['scalar', 'uint16_t'], 'len'],
                ['pad', 2],
                ['data', ['list', '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={'align': '8'}),
            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={'wire_type': 'uint32', 'bitmask': 'False', 'complete': 'True'}),
        ]
        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', ['scalar', 'uint16_t'], 'type'],
                ['data', ['scalar', 'uint16_t'], 'len'],
                ['pad', 4]]],

            ['struct', 'of_queue_prop_min_rate', [], 'of_queue_prop', [
                ['type', ['scalar', 'uint16_t'], 'type', 1],
                ['data', ['scalar', 'uint16_t'], 'len'],
                ['pad', 4],
                ['data', ['scalar', '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()
