#!/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_front_end.frontend_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("standard-1.0", 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("standard-1.0", 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()
