from .autopath import do_autopath
do_autopath()

import warnings
from py.test import raises
from tiramisu import Config ,IPOption, NetworkOption, NetmaskOption, \
    PortOption, BroadcastOption, OptionDescription
from tiramisu.error import ValueWarning


def test_ip():
    a = IPOption('a', '')
    b = IPOption('b', '', private_only=True)
    d = IPOption('d', '', warnings_only=True, private_only=True)
    warnings.simplefilter("always", ValueWarning)
    od = OptionDescription('od', '', [a, b, d])
    config = Config(od)
    config.option('a').value.set('192.168.1.1')
    config.option('a').value.set('192.168.1.0')
    config.option('a').value.set('88.88.88.88')
    config.option('a').value.set('0.0.0.0')
    raises(ValueError, "config.option('a').value.set('255.255.255.0')")
    config.option('b').value.set('192.168.1.1')
    config.option('b').value.set('192.168.1.0')
    raises(ValueError, "config.option('b').value.set('88.88.88.88')")
    config.option('b').value.set('0.0.0.0')
    raises(ValueError, "config.option('b').value.set('255.255.255.0')")
    raises(ValueError, "config.option('a').value.set('333.0.1.20')")

    raises(ValueError, "IPOption('a', 'ip', default='192.000.023.01')")
    with warnings.catch_warnings(record=True) as w:
        config.option('d').value.set('88.88.88.88')
    assert len(w) == 1


def test_ip_default():
    a = IPOption('a', '', '88.88.88.88')
    od = OptionDescription('od', '', [a])
    c = Config(od)
    c.option('a').value.get() == '88.88.88.88'


def test_ip_reserved():
    a = IPOption('a', '')
    b = IPOption('b', '', allow_reserved=True)
    c = IPOption('c', '', warnings_only=True)
    od = OptionDescription('od', '', [a, b, c])
    warnings.simplefilter("always", ValueWarning)
    cfg = Config(od)
    raises(ValueError, "cfg.option('a').value.set('226.94.1.1')")
    cfg.option('b').value.set('226.94.1.1')
    with warnings.catch_warnings(record=True) as w:
        cfg.option('c').value.set('226.94.1.1')
    assert len(w) == 1


def test_network():
    a = NetworkOption('a', '')
    b = NetworkOption('b', '', warnings_only=True)
    od = OptionDescription('od', '', [a, b])
    warnings.simplefilter("always", ValueWarning)
    cfg = Config(od)
    cfg.option('a').value.set('192.168.1.1')
    cfg.option('a').value.set('192.168.1.0')
    cfg.option('a').value.set('88.88.88.88')
    cfg.option('a').value.set('0.0.0.0')
    raises(ValueError, "cfg.option('a').value.set(1)")
    raises(ValueError, "cfg.option('a').value.set('1.1.1.1.1')")
    raises(ValueError, "cfg.option('a').value.set('255.255.255.0')")
    raises(ValueError, "cfg.option('a').value.set('192.168.001.0')")
    raises(ValueError, "cfg.option('a').value.set('333.168.1.1')")
    with warnings.catch_warnings(record=True) as w:
        cfg.option('b').value.set('255.255.255.0')
    assert len(w) == 1


def test_network_invalid():
    raises(ValueError, "NetworkOption('a', '', default='toto')")


def test_netmask():
    a = NetmaskOption('a', '')
    od = OptionDescription('od', '', [a])
    cfg = Config(od)
    raises(ValueError, "cfg.option('a').value.set('192.168.1.1.1')")
    raises(ValueError, "cfg.option('a').value.set('192.168.1.1')")
    raises(ValueError, "cfg.option('a').value.set('192.168.1.0')")
    raises(ValueError, "cfg.option('a').value.set('88.88.88.88')")
    raises(ValueError, "cfg.option('a').value.set('255.255.255.000')")
    raises(ValueError, "cfg.option('a').value.set(2)")
    cfg.option('a').value.set('0.0.0.0')
    cfg.option('a').value.set('255.255.255.0')


def test_broadcast():
    a = BroadcastOption('a', '')
    od = OptionDescription('od', '', [a])
    cfg = Config(od)
    raises(ValueError, "cfg.option('a').value.set('192.168.1.255.1')")
    raises(ValueError, "cfg.option('a').value.set('192.168.001.255')")
    raises(ValueError, "cfg.option('a').value.set('192.168.0.300')")
    raises(ValueError, "cfg.option('a').value.set(1)")
    raises(ValueError, "cfg.option('a').value.set(2)")
    cfg.option('a').value.set('0.0.0.0')
    cfg.option('a').value.set('255.255.255.0')


def test_port():
    a = PortOption('a', '')
    b = PortOption('b', '', allow_zero=True)
    c = PortOption('c', '', allow_zero=True, allow_registred=False)
    d = PortOption('d', '', allow_zero=True, allow_wellknown=False, allow_registred=False)
    e = PortOption('e', '', allow_zero=True, allow_private=True)
    f = PortOption('f', '', allow_private=True)
    od = OptionDescription('od', '', [a, b, c, d, e, f])
    cfg = Config(od)
    raises(ValueError, "cfg.option('a').value.set(0)")
    cfg.option('a').value.set(1)
    cfg.option('a').value.set(1023)
    cfg.option('a').value.set(1024)
    cfg.option('a').value.set(49151)
    raises(ValueError, "cfg.option('a').value.set(49152)")
    raises(ValueError, "cfg.option('a').value.set(65535)")
    raises(ValueError, "cfg.option('a').value.set(65536)")

    cfg.option('b').value.set(0)
    cfg.option('b').value.set(1)
    cfg.option('b').value.set(1023)
    cfg.option('b').value.set(1024)
    cfg.option('b').value.set(49151)
    raises(ValueError, "cfg.option('b').value.set(49152)")
    raises(ValueError, "cfg.option('b').value.set(65535)")
    raises(ValueError, "cfg.option('b').value.set(65536)")

    cfg.option('c').value.set(0)
    cfg.option('c').value.set(1)
    cfg.option('c').value.set(1023)
    raises(ValueError, "cfg.option('c').value.set(1024)")
    raises(ValueError, "cfg.option('c').value.set(49151)")
    raises(ValueError, "cfg.option('c').value.set(49152)")
    raises(ValueError, "cfg.option('c').value.set(65535)")
    raises(ValueError, "cfg.option('c').value.set(65536)")

    cfg.option('d').value.set(0)
    raises(ValueError, "cfg.option('d').value.set(1)")
    raises(ValueError, "cfg.option('d').value.set(1023)")
    raises(ValueError, "cfg.option('d').value.set(1024)")
    raises(ValueError, "cfg.option('d').value.set(49151)")
    raises(ValueError, "cfg.option('d').value.set(49152)")
    raises(ValueError, "cfg.option('d').value.set(65535)")
    raises(ValueError, "cfg.option('d').value.set(65536)")

    cfg.option('e').value.set(0)
    cfg.option('e').value.set(1)
    cfg.option('e').value.set(1023)
    cfg.option('e').value.set(1024)
    cfg.option('e').value.set(49151)
    cfg.option('e').value.set(49152)
    cfg.option('e').value.set(65535)

    raises(ValueError, "cfg.option('f').value.set(0)")
    cfg.option('f').value.set(1)
    cfg.option('f').value.set(1023)
    cfg.option('f').value.set(1024)
    cfg.option('f').value.set(49151)
    cfg.option('f').value.set(49152)
    cfg.option('f').value.set(65535)
    raises(ValueError, "cfg.option('f').value.set(65536)")


def test_port_range():
    a = PortOption('a', '', allow_range=True)
    b = PortOption('b', '', allow_range=True, allow_zero=True)
    c = PortOption('c', '', allow_range=True, allow_zero=True, allow_registred=False)
    d = PortOption('d', '', allow_range=True, allow_zero=True, allow_wellknown=False, allow_registred=False)
    e = PortOption('e', '', allow_range=True, allow_zero=True, allow_private=True)
    f = PortOption('f', '', allow_range=True, allow_private=True)
    od = OptionDescription('od', '', [a, b, c, d, e, f])
    cfg = Config(od)
    raises(ValueError, "cfg.option('a').value.set(0)")
    cfg.option('a').value.set(1)
    cfg.option('a').value.set(1023)
    cfg.option('a').value.set(1024)
    cfg.option('a').value.set(49151)
    raises(ValueError, "cfg.option('a').value.set(49152)")
    raises(ValueError, "cfg.option('a').value.set(65535)")
    raises(ValueError, "cfg.option('a').value.set(65536)")
    cfg.option('a').value.set('1:49151')
    raises(ValueError, "cfg.option('a').value.set('0:49151')")
    raises(ValueError, "cfg.option('a').value.set('1:49152')")

    cfg.option('b').value.set(0)
    cfg.option('b').value.set(1)
    cfg.option('b').value.set(1023)
    cfg.option('b').value.set(1024)
    cfg.option('b').value.set(49151)
    raises(ValueError, "cfg.option('b').value.set(49152)")
    raises(ValueError, "cfg.option('b').value.set(65535)")
    raises(ValueError, "cfg.option('b').value.set(65536)")
    cfg.option('b').value.set('0:49151')
    raises(ValueError, "cfg.option('b').value.set('0:49152')")

    cfg.option('c').value.set(0)
    cfg.option('c').value.set(1)
    cfg.option('c').value.set(1023)
    raises(ValueError, "cfg.option('c').value.set(1024)")
    raises(ValueError, "cfg.option('c').value.set(49151)")
    raises(ValueError, "cfg.option('c').value.set(49152)")
    raises(ValueError, "cfg.option('c').value.set(65535)")
    raises(ValueError, "cfg.option('c').value.set(65536)")
    cfg.option('c').value.set('0:1023')
    raises(ValueError, "cfg.option('c').value.set('0:1024')")

    cfg.option('d').value.set(0)
    raises(ValueError, "cfg.option('d').value.set(1)")
    raises(ValueError, "cfg.option('d').value.set(1023)")
    raises(ValueError, "cfg.option('d').value.set(1024)")
    raises(ValueError, "cfg.option('d').value.set(49151)")
    raises(ValueError, "cfg.option('d').value.set(49152)")
    raises(ValueError, "cfg.option('d').value.set(65535)")
    raises(ValueError, "cfg.option('d').value.set(65536)")
    raises(ValueError, "cfg.option('d').value.set('0:0')")
    raises(ValueError, "cfg.option('d').value.set('0:1')")

    cfg.option('e').value.set(0)
    cfg.option('e').value.set(1)
    cfg.option('e').value.set(1023)
    cfg.option('e').value.set(1024)
    cfg.option('e').value.set(49151)
    cfg.option('e').value.set(49152)
    cfg.option('e').value.set(65535)
    cfg.option('e').value.set('0:65535')
    raises(ValueError, "cfg.option('e').value.set('0:65536')")

    raises(ValueError, "cfg.option('f').value.set(0)")
    cfg.option('f').value.set(1)
    cfg.option('f').value.set(1023)
    cfg.option('f').value.set(1024)
    cfg.option('f').value.set(49151)
    cfg.option('f').value.set(49152)
    cfg.option('f').value.set(65535)
    raises(ValueError, "cfg.option('f').value.set(65536)")
    cfg.option('f').value.set('1:65535')
    cfg.option('f').value.set('3:4')
    raises(ValueError, "cfg.option('f').value.set('0:65535')")
    raises(ValueError, "cfg.option('f').value.set('4:3')")