#!/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 difflib
import test_data

# Human-friendly format for binary strings. 8 bytes per line.
def format_binary(buf):
    byts = map(ord, buf)
    lines = [[]]
    for byt in byts:
        if len(lines[-1]) == 8:
            lines.append([])
        lines[-1].append(byt)
    return '\n'.join([' '.join(['%02x' % y for y in x]) for x in lines])

def diff(a, b):
    return '\n'.join(difflib.ndiff(a.splitlines(), b.splitlines()))

# Test serialization / deserialization of a sample object.
# Depends on the __eq__ method being correct.
def test_serialization(obj, buf):
    packed = obj.pack()
    if packed != buf:
        a = format_binary(buf)
        b = format_binary(packed)
        raise AssertionError("Serialization of %s failed\nExpected:\n%s\nActual:\n%s\nDiff:\n%s" % \
            (type(obj).__name__, a, b, diff(a, b)))
    unpacked = type(obj).unpack(buf)
    if obj != unpacked:
        a = obj.show()
        b = unpacked.show()
        raise AssertionError("Deserialization of %s failed\nExpected:\n%s\nActual:\n%s\nDiff:\n%s" % \
            (type(obj).__name__, a, b, diff(a, b)))

def test_pretty(obj, expected):
    pretty = obj.show()
    if expected != pretty:
        raise AssertionError("Pretty printing of %s failed\nExpected:\n%s\nActual:\n%s\nDiff:\n%s" % \
            (type(obj).__name__, expected, pretty, diff(expected, pretty)))

# Run test_serialization and possibly test_pretty against the named data file
# Uses the globals of the calling function to get 'ofp'
def test_datafile(name):
    data = test_data.read(name)
    binary = data['binary']
    python = data['python']
    obj = eval(python, sys._getframe(1).f_globals)
    test_serialization(obj, binary)
    if 'python pretty-printer' in data:
        test_pretty(obj, data['python pretty-printer'])
